Move "Open Full Screen" to React Panel (#449)
This commit is contained in:
parent
6c90ef2e62
commit
8629bcbe2d
|
@ -7288,6 +7288,11 @@
|
|||
"tiny-emitter": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"clipboard-copy": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-4.0.1.tgz",
|
||||
"integrity": "sha512-wOlqdqziE/NNTUJsfSgXmBMIrYmfd5V0HCGsR8uAKHcg+h9NENWINcfRjtWGU77wDHC8B8ijV4hMTGYbrKovng=="
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
"bootstrap": "3.4.1",
|
||||
"canvas": "file:./canvas",
|
||||
"clean-webpack-plugin": "0.1.19",
|
||||
"clipboard-copy": "4.0.1",
|
||||
"copy-webpack-plugin": "6.0.2",
|
||||
"crossroads": "0.12.2",
|
||||
"css-element-queries": "1.1.1",
|
||||
|
|
|
@ -108,7 +108,7 @@ export interface CollectionBase extends TreeNode {
|
|||
isCollectionExpanded: ko.Observable<boolean>;
|
||||
|
||||
onDocumentDBDocumentsClick(): void;
|
||||
onNewQueryClick(source: any, event: MouseEvent, queryText?: string): void;
|
||||
onNewQueryClick(source: any, event?: MouseEvent, queryText?: string): void;
|
||||
expandCollection(): void;
|
||||
collapseCollection(): void;
|
||||
getDatabase(): Database;
|
||||
|
@ -140,11 +140,11 @@ export interface Collection extends CollectionBase {
|
|||
onSettingsClick: () => Promise<void>;
|
||||
|
||||
onNewGraphClick(): void;
|
||||
onNewMongoQueryClick(source: any, event: MouseEvent, queryText?: string): void;
|
||||
onNewMongoQueryClick(source: any, event?: MouseEvent, queryText?: string): void;
|
||||
onNewMongoShellClick(): void;
|
||||
onNewStoredProcedureClick(source: Collection, event: MouseEvent): void;
|
||||
onNewUserDefinedFunctionClick(source: Collection, event: MouseEvent): void;
|
||||
onNewTriggerClick(source: Collection, event: MouseEvent): void;
|
||||
onNewStoredProcedureClick(source: Collection, event?: MouseEvent): void;
|
||||
onNewUserDefinedFunctionClick(source: Collection, event?: MouseEvent): void;
|
||||
onNewTriggerClick(source: Collection, event?: MouseEvent): void;
|
||||
storedProcedures: ko.Computed<StoredProcedure[]>;
|
||||
userDefinedFunctions: ko.Computed<UserDefinedFunction[]>;
|
||||
triggers: ko.Computed<Trigger[]>;
|
||||
|
|
|
@ -33,7 +33,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"_isAfecFeatureRegistered": [Function],
|
||||
"_isInitializingNotebooks": false,
|
||||
"_isSystemDatabasePredicate": [Function],
|
||||
"_openShareDialog": [Function],
|
||||
"_panes": Array [
|
||||
AddDatabasePane {
|
||||
"autoPilotUsageCost": [Function],
|
||||
|
@ -940,8 +939,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"isPreferredApiMongoDB": [Function],
|
||||
"isPreferredApiTable": [Function],
|
||||
"isPublishNotebookPaneEnabled": [Function],
|
||||
"isReadToggled": [Function],
|
||||
"isReadWriteToggled": [Function],
|
||||
"isRefreshingExplorer": [Function],
|
||||
"isResourceTokenCollectionNodeSelected": [Function],
|
||||
"isRightPanelV2Enabled": [Function],
|
||||
|
@ -996,7 +993,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"openDialog": undefined,
|
||||
"openSidePanel": undefined,
|
||||
"provideFeedbackEmail": [Function],
|
||||
|
@ -1027,8 +1023,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"refreshDatabaseAccount": [Function],
|
||||
"refreshNotebookList": [Function],
|
||||
"refreshTreeTitle": [Function],
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
|
@ -1124,12 +1118,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"shareAccessData": [Function],
|
||||
"shareAccessToggleState": [Function],
|
||||
"shareAccessUrl": [Function],
|
||||
"shareTokenCopyHelperText": [Function],
|
||||
"shareUrlCopyHelperText": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splitter": Splitter {
|
||||
|
@ -1189,9 +1177,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"openedTabs": [Function],
|
||||
},
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
|
@ -1266,7 +1251,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"_isAfecFeatureRegistered": [Function],
|
||||
"_isInitializingNotebooks": false,
|
||||
"_isSystemDatabasePredicate": [Function],
|
||||
"_openShareDialog": [Function],
|
||||
"_panes": Array [
|
||||
AddDatabasePane {
|
||||
"autoPilotUsageCost": [Function],
|
||||
|
@ -2173,8 +2157,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"isPreferredApiMongoDB": [Function],
|
||||
"isPreferredApiTable": [Function],
|
||||
"isPublishNotebookPaneEnabled": [Function],
|
||||
"isReadToggled": [Function],
|
||||
"isReadWriteToggled": [Function],
|
||||
"isRefreshingExplorer": [Function],
|
||||
"isResourceTokenCollectionNodeSelected": [Function],
|
||||
"isRightPanelV2Enabled": [Function],
|
||||
|
@ -2229,7 +2211,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"openDialog": undefined,
|
||||
"openSidePanel": undefined,
|
||||
"provideFeedbackEmail": [Function],
|
||||
|
@ -2260,8 +2241,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"refreshDatabaseAccount": [Function],
|
||||
"refreshNotebookList": [Function],
|
||||
"refreshTreeTitle": [Function],
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
|
@ -2357,12 +2336,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"shareAccessData": [Function],
|
||||
"shareAccessToggleState": [Function],
|
||||
"shareAccessUrl": [Function],
|
||||
"shareTokenCopyHelperText": [Function],
|
||||
"shareUrlCopyHelperText": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splitter": Splitter {
|
||||
|
@ -2422,9 +2395,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"openedTabs": [Function],
|
||||
},
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
|
@ -2512,7 +2482,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"_isAfecFeatureRegistered": [Function],
|
||||
"_isInitializingNotebooks": false,
|
||||
"_isSystemDatabasePredicate": [Function],
|
||||
"_openShareDialog": [Function],
|
||||
"_panes": Array [
|
||||
AddDatabasePane {
|
||||
"autoPilotUsageCost": [Function],
|
||||
|
@ -3419,8 +3388,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"isPreferredApiMongoDB": [Function],
|
||||
"isPreferredApiTable": [Function],
|
||||
"isPublishNotebookPaneEnabled": [Function],
|
||||
"isReadToggled": [Function],
|
||||
"isReadWriteToggled": [Function],
|
||||
"isRefreshingExplorer": [Function],
|
||||
"isResourceTokenCollectionNodeSelected": [Function],
|
||||
"isRightPanelV2Enabled": [Function],
|
||||
|
@ -3475,7 +3442,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"openDialog": undefined,
|
||||
"openSidePanel": undefined,
|
||||
"provideFeedbackEmail": [Function],
|
||||
|
@ -3506,8 +3472,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"refreshDatabaseAccount": [Function],
|
||||
"refreshNotebookList": [Function],
|
||||
"refreshTreeTitle": [Function],
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
|
@ -3603,12 +3567,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"shareAccessData": [Function],
|
||||
"shareAccessToggleState": [Function],
|
||||
"shareAccessUrl": [Function],
|
||||
"shareTokenCopyHelperText": [Function],
|
||||
"shareUrlCopyHelperText": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splitter": Splitter {
|
||||
|
@ -3668,9 +3626,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"openedTabs": [Function],
|
||||
},
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
|
@ -3745,7 +3700,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"_isAfecFeatureRegistered": [Function],
|
||||
"_isInitializingNotebooks": false,
|
||||
"_isSystemDatabasePredicate": [Function],
|
||||
"_openShareDialog": [Function],
|
||||
"_panes": Array [
|
||||
AddDatabasePane {
|
||||
"autoPilotUsageCost": [Function],
|
||||
|
@ -4652,8 +4606,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"isPreferredApiMongoDB": [Function],
|
||||
"isPreferredApiTable": [Function],
|
||||
"isPublishNotebookPaneEnabled": [Function],
|
||||
"isReadToggled": [Function],
|
||||
"isReadWriteToggled": [Function],
|
||||
"isRefreshingExplorer": [Function],
|
||||
"isResourceTokenCollectionNodeSelected": [Function],
|
||||
"isRightPanelV2Enabled": [Function],
|
||||
|
@ -4708,7 +4660,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"openDialog": undefined,
|
||||
"openSidePanel": undefined,
|
||||
"provideFeedbackEmail": [Function],
|
||||
|
@ -4739,8 +4690,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"refreshDatabaseAccount": [Function],
|
||||
"refreshNotebookList": [Function],
|
||||
"refreshTreeTitle": [Function],
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
|
@ -4836,12 +4785,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"shareAccessData": [Function],
|
||||
"shareAccessToggleState": [Function],
|
||||
"shareAccessUrl": [Function],
|
||||
"shareTokenCopyHelperText": [Function],
|
||||
"shareUrlCopyHelperText": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splitter": Splitter {
|
||||
|
@ -4901,9 +4844,6 @@ exports[`SettingsComponent renders 1`] = `
|
|||
"openedTabs": [Function],
|
||||
},
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
|
|
|
@ -94,16 +94,6 @@ BindingHandlersRegisterer.registerBindingHandlers();
|
|||
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
||||
var tmp = ComponentRegisterer;
|
||||
|
||||
enum ShareAccessToggleState {
|
||||
ReadWrite,
|
||||
Read,
|
||||
}
|
||||
|
||||
interface AdHocAccessData {
|
||||
readWriteUrl: string;
|
||||
readUrl: string;
|
||||
}
|
||||
|
||||
export interface ExplorerParams {
|
||||
setIsNotificationConsoleExpanded: (isExpanded: boolean) => void;
|
||||
setNotificationConsoleData: (consoleData: ConsoleData) => void;
|
||||
|
@ -159,8 +149,8 @@ export default class Explorer {
|
|||
|
||||
// Panes
|
||||
public contextPanes: ContextualPaneBase[];
|
||||
private openSidePanel: (headerText: string, panelContent: JSX.Element) => void;
|
||||
private closeSidePanel: () => void;
|
||||
public openSidePanel: (headerText: string, panelContent: JSX.Element) => void;
|
||||
public closeSidePanel: () => void;
|
||||
|
||||
// Resource Tree
|
||||
public databases: ko.ObservableArray<ViewModels.Database>;
|
||||
|
@ -226,15 +216,6 @@ export default class Explorer {
|
|||
public canExceedMaximumValue: ko.Computed<boolean>;
|
||||
public isAutoscaleDefaultEnabled: ko.Observable<boolean>;
|
||||
|
||||
public shouldShowShareDialogContents: ko.Observable<boolean>;
|
||||
public shareAccessData: ko.Observable<AdHocAccessData>;
|
||||
public renewExplorerShareAccess: (explorer: Explorer, token: string) => Q.Promise<void>;
|
||||
public renewTokenError: ko.Observable<string>;
|
||||
public tokenForRenewal: ko.Observable<string>;
|
||||
public shareAccessToggleState: ko.Observable<ShareAccessToggleState>;
|
||||
public shareAccessUrl: ko.Observable<string>;
|
||||
public shareUrlCopyHelperText: ko.Observable<string>;
|
||||
public shareTokenCopyHelperText: ko.Observable<string>;
|
||||
public isSchemaEnabled: ko.Computed<boolean>;
|
||||
|
||||
// Notebooks
|
||||
|
@ -401,25 +382,6 @@ export default class Explorer {
|
|||
this.resourceTokenCollection = ko.observable<ViewModels.CollectionBase>();
|
||||
this.resourceTokenPartitionKey = ko.observable<string>();
|
||||
this.isAuthWithResourceToken = ko.observable<boolean>(false);
|
||||
|
||||
this.shareAccessData = ko.observable<AdHocAccessData>({
|
||||
readWriteUrl: undefined,
|
||||
readUrl: undefined,
|
||||
});
|
||||
this.tokenForRenewal = ko.observable<string>("");
|
||||
this.renewTokenError = ko.observable<string>("");
|
||||
this.shareAccessUrl = ko.observable<string>();
|
||||
this.shareUrlCopyHelperText = ko.observable<string>("Click to copy");
|
||||
this.shareTokenCopyHelperText = ko.observable<string>("Click to copy");
|
||||
this.shareAccessToggleState = ko.observable<ShareAccessToggleState>(ShareAccessToggleState.ReadWrite);
|
||||
this.shareAccessToggleState.subscribe((toggleState: ShareAccessToggleState) => {
|
||||
if (toggleState === ShareAccessToggleState.ReadWrite) {
|
||||
this.shareAccessUrl(this.shareAccessData && this.shareAccessData().readWriteUrl);
|
||||
} else {
|
||||
this.shareAccessUrl(this.shareAccessData && this.shareAccessData().readUrl);
|
||||
}
|
||||
});
|
||||
this.shouldShowShareDialogContents = ko.observable<boolean>(false);
|
||||
this.isGalleryPublishEnabled = ko.computed<boolean>(
|
||||
() => configContext.ENABLE_GALLERY_PUBLISH || this.isFeatureEnabled(Constants.Features.enableGalleryPublish)
|
||||
);
|
||||
|
@ -1041,123 +1003,6 @@ export default class Explorer {
|
|||
// TODO: return result
|
||||
}
|
||||
|
||||
public copyUrlLink(src: any, event: MouseEvent): void {
|
||||
const urlLinkInput: HTMLInputElement = document.getElementById("shareUrlLink") as HTMLInputElement;
|
||||
urlLinkInput && urlLinkInput.select();
|
||||
document.execCommand("copy");
|
||||
this.shareUrlCopyHelperText("Copied");
|
||||
setTimeout(() => this.shareUrlCopyHelperText("Click to copy"), Constants.ClientDefaults.copyHelperTimeoutMs);
|
||||
|
||||
TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, {
|
||||
description: "Copy full screen URL",
|
||||
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
|
||||
defaultExperience: this.defaultExperience && this.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ShareDialog,
|
||||
});
|
||||
}
|
||||
|
||||
public onCopyUrlLinkKeyPress(src: any, event: KeyboardEvent): boolean {
|
||||
if (event.keyCode === Constants.KeyCodes.Enter || event.keyCode === Constants.KeyCodes.Space) {
|
||||
this.copyUrlLink(src, null);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public copyToken(src: any, event: MouseEvent): void {
|
||||
const tokenInput: HTMLInputElement = document.getElementById("shareToken") as HTMLInputElement;
|
||||
tokenInput && tokenInput.select();
|
||||
document.execCommand("copy");
|
||||
this.shareTokenCopyHelperText("Copied");
|
||||
setTimeout(() => this.shareTokenCopyHelperText("Click to copy"), Constants.ClientDefaults.copyHelperTimeoutMs);
|
||||
}
|
||||
|
||||
public onCopyTokenKeyPress(src: any, event: KeyboardEvent): boolean {
|
||||
if (event.keyCode === Constants.KeyCodes.Enter || event.keyCode === Constants.KeyCodes.Space) {
|
||||
this.copyToken(src, null);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public renewToken = (): void => {
|
||||
TelemetryProcessor.trace(Action.ConnectEncryptionToken);
|
||||
this.renewTokenError("");
|
||||
const id: string = NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.InProgress,
|
||||
"Initiating connection to account"
|
||||
);
|
||||
this.renewExplorerShareAccess(this, this.tokenForRenewal())
|
||||
.fail((error: any) => {
|
||||
const stringifiedError: string = getErrorMessage(error);
|
||||
this.renewTokenError("Invalid connection string specified");
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Error,
|
||||
`Failed to initiate connection to account: ${stringifiedError}`
|
||||
);
|
||||
})
|
||||
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
|
||||
};
|
||||
|
||||
public generateSharedAccessData(): void {
|
||||
const id: string = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Generating share url");
|
||||
AuthHeadersUtil.generateEncryptedToken().then(
|
||||
(tokenResponse: DataModels.GenerateTokenResponse) => {
|
||||
NotificationConsoleUtils.clearInProgressMessageWithId(id);
|
||||
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Info, "Successfully generated share url");
|
||||
this.shareAccessData({
|
||||
readWriteUrl: this._getShareAccessUrlForToken(tokenResponse.readWrite),
|
||||
readUrl: this._getShareAccessUrlForToken(tokenResponse.read),
|
||||
});
|
||||
!this.shareAccessData().readWriteUrl && this.shareAccessToggleState(ShareAccessToggleState.Read); // select read toggle by default for readers
|
||||
this.shareAccessToggleState.valueHasMutated(); // to set initial url and token state
|
||||
this.shareAccessData.valueHasMutated();
|
||||
this._openShareDialog();
|
||||
},
|
||||
(error: any) => {
|
||||
NotificationConsoleUtils.clearInProgressMessageWithId(id);
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
ConsoleDataType.Error,
|
||||
`Failed to generate share url: ${getErrorMessage(error)}`
|
||||
);
|
||||
console.error(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public isConnectExplorerVisible(): boolean {
|
||||
return $("#connectExplorer").is(":visible") || false;
|
||||
}
|
||||
|
||||
public isReadWriteToggled: () => boolean = (): boolean => {
|
||||
return this.shareAccessToggleState() === ShareAccessToggleState.ReadWrite;
|
||||
};
|
||||
|
||||
public isReadToggled: () => boolean = (): boolean => {
|
||||
return this.shareAccessToggleState() === ShareAccessToggleState.Read;
|
||||
};
|
||||
|
||||
public toggleReadWrite: (src: any, event: MouseEvent) => void = (src: any, event: MouseEvent) => {
|
||||
this.shareAccessToggleState(ShareAccessToggleState.ReadWrite);
|
||||
};
|
||||
|
||||
public toggleRead: (src: any, event: MouseEvent) => void = (src: any, event: MouseEvent) => {
|
||||
this.shareAccessToggleState(ShareAccessToggleState.Read);
|
||||
};
|
||||
|
||||
public onToggleKeyDown: (src: any, event: KeyboardEvent) => boolean = (src: any, event: KeyboardEvent) => {
|
||||
if (event.keyCode === Constants.KeyCodes.LeftArrow) {
|
||||
this.toggleReadWrite(src, null);
|
||||
return false;
|
||||
} else if (event.keyCode === Constants.KeyCodes.RightArrow) {
|
||||
this.toggleRead(src, null);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
public isDatabaseNodeOrNoneSelected(): boolean {
|
||||
return this.isNoneSelected() || this.isDatabaseNodeSelected();
|
||||
}
|
||||
|
@ -1824,83 +1669,6 @@ export default class Explorer {
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
// TODO: Abstract this elsewhere
|
||||
private _openShareDialog: () => void = (): void => {
|
||||
if (!$("#shareDataAccessFlyout").dialog("instance")) {
|
||||
const accountMetadataInfo = {
|
||||
databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
|
||||
defaultExperience: this.defaultExperience && this.defaultExperience(),
|
||||
dataExplorerArea: Constants.Areas.ShareDialog,
|
||||
};
|
||||
const openFullscreenButton = {
|
||||
text: "Open",
|
||||
class: "openFullScreenBtn openFullScreenCancelBtn",
|
||||
click: () => {
|
||||
TelemetryProcessor.trace(
|
||||
Action.SelectItem,
|
||||
ActionModifiers.Mark,
|
||||
_.extend({}, { description: "Open full screen" }, accountMetadataInfo)
|
||||
);
|
||||
|
||||
const hiddenAnchorElement: HTMLAnchorElement = document.createElement("a");
|
||||
hiddenAnchorElement.href = this.shareAccessUrl();
|
||||
hiddenAnchorElement.target = "_blank";
|
||||
$("#shareDataAccessFlyout").dialog("close");
|
||||
hiddenAnchorElement.click();
|
||||
},
|
||||
};
|
||||
const cancelButton = {
|
||||
text: "Cancel",
|
||||
class: "shareCancelButton openFullScreenCancelBtn",
|
||||
click: () => {
|
||||
TelemetryProcessor.trace(
|
||||
Action.SelectItem,
|
||||
ActionModifiers.Mark,
|
||||
_.extend({}, { description: "Cancel open full screen" }, accountMetadataInfo)
|
||||
);
|
||||
$("#shareDataAccessFlyout").dialog("close");
|
||||
},
|
||||
};
|
||||
$("#shareDataAccessFlyout").dialog({
|
||||
autoOpen: false,
|
||||
buttons: [openFullscreenButton, cancelButton],
|
||||
closeOnEscape: true,
|
||||
draggable: false,
|
||||
dialogClass: "no-close",
|
||||
position: { my: "right top", at: "right bottom", of: $(".OpenFullScreen") },
|
||||
resizable: false,
|
||||
title: "Open Full Screen",
|
||||
width: 400,
|
||||
close: (event: Event, ui: JQueryUI.DialogUIParams) => this.shouldShowShareDialogContents(false),
|
||||
});
|
||||
$("#shareDataAccessFlyout").dialog("option", "classes", {
|
||||
"ui-widget-content": "shareUrlDialog",
|
||||
"ui-widget-header": "shareUrlTitle",
|
||||
"ui-dialog-titlebar-close": "shareClose",
|
||||
"ui-button": "shareCloseIcon",
|
||||
"ui-button-icon": "cancelIcon",
|
||||
"ui-icon": "",
|
||||
});
|
||||
$("#shareDataAccessFlyout").dialog("option", "open", (event: Event, ui: JQueryUI.DialogUIParams) =>
|
||||
$(".openFullScreenBtn").focus()
|
||||
);
|
||||
}
|
||||
$("#shareDataAccessFlyout").dialog("close");
|
||||
this.shouldShowShareDialogContents(true);
|
||||
$("#shareDataAccessFlyout").dialog("open");
|
||||
};
|
||||
|
||||
private _getShareAccessUrlForToken(token: string): string {
|
||||
if (!token) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const urlPrefixWithKeyParam: string = `${configContext.hostedExplorerURL}?key=`;
|
||||
const currentActiveTab = this.tabsManager.activeTab();
|
||||
|
||||
return `${urlPrefixWithKeyParam}${token}#/${(currentActiveTab && currentActiveTab.hashLocation()) || ""}`;
|
||||
}
|
||||
|
||||
private _initSettings() {
|
||||
if (!ExplorerSettings.hasSettingsDefined()) {
|
||||
ExplorerSettings.createDefaultSettings();
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as ko from "knockout";
|
|||
import * as React from "react";
|
||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { CommandBarComponentButtonFactory } from "./CommandBarComponentButtonFactory";
|
||||
import * as CommandBarComponentButtonFactory from "./CommandBarComponentButtonFactory";
|
||||
import { CommandBar, ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar";
|
||||
import { StyleConstants } from "../../../Common/Constants";
|
||||
import * as CommandBarUtil from "./CommandBarUtil";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as ko from "knockout";
|
||||
import { CommandBarComponentButtonFactory } from "./CommandBarComponentButtonFactory";
|
||||
import * as CommandBarComponentButtonFactory from "./CommandBarComponentButtonFactory";
|
||||
import { GitHubOAuthService } from "../../../GitHub/GitHubOAuthService";
|
||||
import NotebookManager from "../../Notebook/NotebookManager";
|
||||
import Explorer from "../../Explorer";
|
||||
|
|
|
@ -1,616 +0,0 @@
|
|||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import { Areas } from "../../../Common/Constants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
import AddDatabaseIcon from "../../../../images/AddDatabase.svg";
|
||||
import AddCollectionIcon from "../../../../images/AddCollection.svg";
|
||||
import AddSqlQueryIcon from "../../../../images/AddSqlQuery_16x16.svg";
|
||||
import BrowseQueriesIcon from "../../../../images/BrowseQuery.svg";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import OpenInTabIcon from "../../../../images/open-in-tab.svg";
|
||||
import OpenQueryFromDiskIcon from "../../../../images/OpenQueryFromDisk.svg";
|
||||
import CosmosTerminalIcon from "../../../../images/Cosmos-Terminal.svg";
|
||||
import HostedTerminalIcon from "../../../../images/Hosted-Terminal.svg";
|
||||
import AddStoredProcedureIcon from "../../../../images/AddStoredProcedure.svg";
|
||||
import SettingsIcon from "../../../../images/settings_15x15.svg";
|
||||
import AddUdfIcon from "../../../../images/AddUdf.svg";
|
||||
import AddTriggerIcon from "../../../../images/AddTrigger.svg";
|
||||
import ScaleIcon from "../../../../images/Scale_15x15.svg";
|
||||
import FeedbackIcon from "../../../../images/Feedback-Command.svg";
|
||||
import EnableNotebooksIcon from "../../../../images/notebook/Notebook-enable.svg";
|
||||
import NewNotebookIcon from "../../../../images/notebook/Notebook-new.svg";
|
||||
import ResetWorkspaceIcon from "../../../../images/notebook/Notebook-reset-workspace.svg";
|
||||
import GitHubIcon from "../../../../images/github.svg";
|
||||
import SynapseIcon from "../../../../images/synapse-link.svg";
|
||||
import { configContext, Platform } from "../../../ConfigContext";
|
||||
import Explorer from "../../Explorer";
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
|
||||
export class CommandBarComponentButtonFactory {
|
||||
private static counter: number = 0;
|
||||
|
||||
public static createStaticCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
if (container.isAuthWithResourceToken()) {
|
||||
return CommandBarComponentButtonFactory.createStaticCommandBarButtonsForResourceToken(container);
|
||||
}
|
||||
|
||||
const newCollectionBtn = CommandBarComponentButtonFactory.createNewCollectionGroup(container);
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
if (container.isFeatureEnabled && container.isFeatureEnabled("regionselectbutton")) {
|
||||
const regions = [{ name: "West US" }, { name: "East US" }, { name: "North Europe" }];
|
||||
buttons.push({
|
||||
iconSrc: null,
|
||||
onCommandClick: () => {},
|
||||
commandButtonLabel: null,
|
||||
hasPopup: false,
|
||||
isDropdown: true,
|
||||
dropdownPlaceholder: "West US",
|
||||
dropdownSelectedKey: "West US",
|
||||
dropdownWidth: 100,
|
||||
children: regions.map(
|
||||
(region) =>
|
||||
({
|
||||
iconSrc: null,
|
||||
onCommandClick: () => {},
|
||||
commandButtonLabel: region.name,
|
||||
dropdownItemKey: region.name,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: "",
|
||||
} as CommandButtonComponentProps)
|
||||
),
|
||||
ariaLabel: "",
|
||||
});
|
||||
}
|
||||
|
||||
buttons.push(newCollectionBtn);
|
||||
|
||||
const addSynapseLink = CommandBarComponentButtonFactory.createOpenSynapseLinkDialogButton(container);
|
||||
if (addSynapseLink) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createDivider());
|
||||
buttons.push(addSynapseLink);
|
||||
}
|
||||
|
||||
if (!container.isPreferredApiTable()) {
|
||||
newCollectionBtn.children = [CommandBarComponentButtonFactory.createNewCollectionGroup(container)];
|
||||
const newDatabaseBtn = CommandBarComponentButtonFactory.createNewDatabase(container);
|
||||
newCollectionBtn.children.push(newDatabaseBtn);
|
||||
}
|
||||
|
||||
buttons.push(CommandBarComponentButtonFactory.createDivider());
|
||||
|
||||
if (container.isNotebookEnabled()) {
|
||||
const newNotebookButton = CommandBarComponentButtonFactory.createNewNotebookButton(container);
|
||||
newNotebookButton.children = [
|
||||
CommandBarComponentButtonFactory.createNewNotebookButton(container),
|
||||
CommandBarComponentButtonFactory.createuploadNotebookButton(container),
|
||||
];
|
||||
buttons.push(newNotebookButton);
|
||||
|
||||
if (container.notebookManager?.gitHubOAuthService) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createManageGitHubAccountButton(container));
|
||||
}
|
||||
}
|
||||
|
||||
if (!container.isRunningOnNationalCloud()) {
|
||||
if (!container.isNotebookEnabled()) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createEnableNotebooksButton(container));
|
||||
}
|
||||
|
||||
if (container.isPreferredApiMongoDB()) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createOpenMongoTerminalButton(container));
|
||||
}
|
||||
|
||||
if (container.isPreferredApiCassandra()) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createOpenCassandraTerminalButton(container));
|
||||
}
|
||||
}
|
||||
|
||||
if (container.isNotebookEnabled()) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createOpenTerminalButton(container));
|
||||
|
||||
buttons.push(CommandBarComponentButtonFactory.createNotebookWorkspaceResetButton(container));
|
||||
}
|
||||
|
||||
if (!container.isDatabaseNodeOrNoneSelected()) {
|
||||
if (container.isNotebookEnabled()) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createDivider());
|
||||
}
|
||||
|
||||
const isSqlQuerySupported = container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||
if (isSqlQuerySupported) {
|
||||
const newSqlQueryBtn = CommandBarComponentButtonFactory.createNewSQLQueryButton(container);
|
||||
buttons.push(newSqlQueryBtn);
|
||||
}
|
||||
|
||||
const isSupportedOpenQueryApi =
|
||||
container.isPreferredApiDocumentDB() || container.isPreferredApiMongoDB() || container.isPreferredApiGraph();
|
||||
const isSupportedOpenQueryFromDiskApi = container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||
if (isSupportedOpenQueryApi && container.selectedNode() && container.findSelectedCollection()) {
|
||||
const openQueryBtn = CommandBarComponentButtonFactory.createOpenQueryButton(container);
|
||||
openQueryBtn.children = [
|
||||
CommandBarComponentButtonFactory.createOpenQueryButton(container),
|
||||
CommandBarComponentButtonFactory.createOpenQueryFromDiskButton(container),
|
||||
];
|
||||
buttons.push(openQueryBtn);
|
||||
} else if (isSupportedOpenQueryFromDiskApi && container.selectedNode() && container.findSelectedCollection()) {
|
||||
buttons.push(CommandBarComponentButtonFactory.createOpenQueryFromDiskButton(container));
|
||||
}
|
||||
|
||||
if (CommandBarComponentButtonFactory.areScriptsSupported(container)) {
|
||||
const label = "New Stored Procedure";
|
||||
const newStoredProcedureBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddStoredProcedureIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection, null);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
|
||||
newStoredProcedureBtn.children = CommandBarComponentButtonFactory.createScriptCommandButtons(container);
|
||||
buttons.push(newStoredProcedureBtn);
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
public static createContextCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
if (!container.isDatabaseNodeOrNoneSelected() && container.isPreferredApiMongoDB()) {
|
||||
const label = "New Shell";
|
||||
const newMongoShellBtn: CommandButtonComponentProps = {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && (<any>selectedCollection).onNewMongoShellClick();
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected() && container.isPreferredApiMongoDB(),
|
||||
};
|
||||
buttons.push(newMongoShellBtn);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
public static createControlCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
if (configContext.platform === Platform.Hosted) {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
if (!container.isPreferredApiCassandra()) {
|
||||
const label = "Settings";
|
||||
const settingsPaneButton: CommandButtonComponentProps = {
|
||||
iconSrc: SettingsIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.settingsPane.open(),
|
||||
commandButtonLabel: null,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
hasPopup: true,
|
||||
disabled: false,
|
||||
};
|
||||
buttons.push(settingsPaneButton);
|
||||
}
|
||||
|
||||
if (container.isHostedDataExplorerEnabled()) {
|
||||
const label = "Open Full Screen";
|
||||
const fullScreenButton: CommandButtonComponentProps = {
|
||||
iconSrc: OpenInTabIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.generateSharedAccessData(),
|
||||
commandButtonLabel: null,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
hasPopup: false,
|
||||
disabled: !container.isHostedDataExplorerEnabled(),
|
||||
className: "OpenFullScreen",
|
||||
};
|
||||
buttons.push(fullScreenButton);
|
||||
}
|
||||
|
||||
if (configContext.platform !== Platform.Emulator) {
|
||||
const label = "Feedback";
|
||||
const feedbackButtonOptions: CommandButtonComponentProps = {
|
||||
iconSrc: FeedbackIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.provideFeedbackEmail(),
|
||||
commandButtonLabel: null,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
};
|
||||
buttons.push(feedbackButtonOptions);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
public static createDivider(): CommandButtonComponentProps {
|
||||
const label = `divider${CommandBarComponentButtonFactory.counter++}`;
|
||||
return {
|
||||
isDivider: true,
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
iconSrc: null,
|
||||
iconAlt: null,
|
||||
onCommandClick: null,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static areScriptsSupported(container: Explorer): boolean {
|
||||
return container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||
}
|
||||
|
||||
private static createNewCollectionGroup(container: Explorer): CommandButtonComponentProps {
|
||||
const label = container.addCollectionText();
|
||||
return {
|
||||
iconSrc: AddCollectionIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.onNewCollectionClicked(),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
id: "createNewContainerCommandButton",
|
||||
};
|
||||
}
|
||||
|
||||
private static createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (container.isServerlessEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
container.databaseAccount &&
|
||||
container.databaseAccount() &&
|
||||
container.databaseAccount().properties &&
|
||||
container.databaseAccount().properties.enableAnalyticalStorage
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const capabilities =
|
||||
(container.databaseAccount &&
|
||||
container.databaseAccount() &&
|
||||
container.databaseAccount().properties &&
|
||||
container.databaseAccount().properties.capabilities) ||
|
||||
[];
|
||||
if (capabilities.some((capability) => capability.name === Constants.CapabilityNames.EnableStorageAnalytics)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const label = "Enable Azure Synapse Link";
|
||||
return {
|
||||
iconSrc: SynapseIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.openEnableSynapseLinkDialog(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: container.isSynapseLinkUpdating(),
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static createNewDatabase(container: Explorer): CommandButtonComponentProps {
|
||||
const label = container.addDatabaseText();
|
||||
return {
|
||||
iconSrc: AddDatabaseIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
container.addDatabasePane.open();
|
||||
document.getElementById("linkAddDatabase").focus();
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
};
|
||||
}
|
||||
|
||||
private static createNewSQLQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (container.isPreferredApiDocumentDB() || container.isPreferredApiGraph()) {
|
||||
const label = "New SQL Query";
|
||||
return {
|
||||
iconSrc: AddSqlQueryIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewQueryClick(selectedCollection, null);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
} else if (container.isPreferredApiMongoDB()) {
|
||||
const label = "New Query";
|
||||
return {
|
||||
iconSrc: AddSqlQueryIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && (<any>selectedCollection).onNewMongoQueryClick(selectedCollection, null);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static createScriptCommandButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
const shouldEnableScriptsCommands: boolean =
|
||||
!container.isDatabaseNodeOrNoneSelected() && CommandBarComponentButtonFactory.areScriptsSupported(container);
|
||||
|
||||
if (shouldEnableScriptsCommands) {
|
||||
const label = "New Stored Procedure";
|
||||
const newStoredProcedureBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddStoredProcedureIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection, null);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
buttons.push(newStoredProcedureBtn);
|
||||
}
|
||||
|
||||
if (shouldEnableScriptsCommands) {
|
||||
const label = "New UDF";
|
||||
const newUserDefinedFunctionBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddUdfIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewUserDefinedFunctionClick(selectedCollection, null);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
buttons.push(newUserDefinedFunctionBtn);
|
||||
}
|
||||
|
||||
if (shouldEnableScriptsCommands) {
|
||||
const label = "New Trigger";
|
||||
const newTriggerBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddTriggerIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewTriggerClick(selectedCollection, null);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
buttons.push(newTriggerBtn);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
private static createNewNotebookButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "New Notebook";
|
||||
return {
|
||||
iconSrc: NewNotebookIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.onNewNotebookClicked(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static createuploadNotebookButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Upload to Notebook Server";
|
||||
return {
|
||||
iconSrc: NewNotebookIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.onUploadToNotebookServerClicked(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static createOpenQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Query";
|
||||
return {
|
||||
iconSrc: BrowseQueriesIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.browseQueriesPane.open(),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
private static createOpenQueryFromDiskButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Query From Disk";
|
||||
return {
|
||||
iconSrc: OpenQueryFromDiskIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.loadQueryPane.open(),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
private static createEnableNotebooksButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return null;
|
||||
}
|
||||
const label = "Enable Notebooks (Preview)";
|
||||
const tooltip =
|
||||
"Notebooks are not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||
const description =
|
||||
"Looks like you have not yet created a notebooks workspace for this account. To proceed and start using notebooks, we'll need to create a default notebooks workspace in this account.";
|
||||
return {
|
||||
iconSrc: EnableNotebooksIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.setupNotebooksPane.openWithTitleAndDescription(label, description),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: !container.isNotebooksEnabledForAccount(),
|
||||
ariaLabel: label,
|
||||
tooltipText: container.isNotebooksEnabledForAccount() ? "" : tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
private static createOpenTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Terminal";
|
||||
return {
|
||||
iconSrc: CosmosTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.openNotebookTerminal(ViewModels.TerminalKind.Default),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static createOpenMongoTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Mongo Shell";
|
||||
const tooltip =
|
||||
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||
const title = "Set up workspace";
|
||||
const description =
|
||||
"Looks like you have not created a workspace for this account. To proceed and start using features including mongo shell and notebook, we will need to create a default workspace in this account.";
|
||||
const disableButton = !container.isNotebooksEnabledForAccount() && !container.isNotebookEnabled();
|
||||
return {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (container.isNotebookEnabled()) {
|
||||
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
|
||||
} else {
|
||||
container.setupNotebooksPane.openWithTitleAndDescription(title, description);
|
||||
}
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: disableButton,
|
||||
ariaLabel: label,
|
||||
tooltipText: !disableButton ? "" : tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
private static createOpenCassandraTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Cassandra Shell";
|
||||
const tooltip =
|
||||
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||
const title = "Set up workspace";
|
||||
const description =
|
||||
"Looks like you have not created a workspace for this account. To proceed and start using features including cassandra shell and notebook, we will need to create a default workspace in this account.";
|
||||
const disableButton = !container.isNotebooksEnabledForAccount() && !container.isNotebookEnabled();
|
||||
return {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (container.isNotebookEnabled()) {
|
||||
container.openNotebookTerminal(ViewModels.TerminalKind.Cassandra);
|
||||
} else {
|
||||
container.setupNotebooksPane.openWithTitleAndDescription(title, description);
|
||||
}
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: disableButton,
|
||||
ariaLabel: label,
|
||||
tooltipText: !disableButton ? "" : tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
private static createNotebookWorkspaceResetButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Reset Workspace";
|
||||
return {
|
||||
iconSrc: ResetWorkspaceIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.resetNotebookWorkspace(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static createManageGitHubAccountButton(container: Explorer): CommandButtonComponentProps {
|
||||
let connectedToGitHub: boolean = container.notebookManager?.gitHubOAuthService.isLoggedIn();
|
||||
const label = connectedToGitHub ? "Manage GitHub settings" : "Connect to GitHub";
|
||||
return {
|
||||
iconSrc: GitHubIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (!connectedToGitHub) {
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubConnect, ActionModifiers.Mark, {
|
||||
databaseAccountName: container.databaseAccount() && container.databaseAccount().name,
|
||||
defaultExperience: container.defaultExperience && container.defaultExperience(),
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
}
|
||||
container.gitHubReposPane.open();
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
private static createStaticCommandBarButtonsForResourceToken(container: Explorer): CommandButtonComponentProps[] {
|
||||
const newSqlQueryBtn = CommandBarComponentButtonFactory.createNewSQLQueryButton(container);
|
||||
const openQueryBtn = CommandBarComponentButtonFactory.createOpenQueryButton(container);
|
||||
|
||||
newSqlQueryBtn.disabled = !container.isResourceTokenCollectionNodeSelected();
|
||||
newSqlQueryBtn.onCommandClick = () => {
|
||||
const resourceTokenCollection: ViewModels.CollectionBase = container.resourceTokenCollection();
|
||||
resourceTokenCollection && resourceTokenCollection.onNewQueryClick(resourceTokenCollection, undefined);
|
||||
};
|
||||
|
||||
openQueryBtn.disabled = !container.isResourceTokenCollectionNodeSelected();
|
||||
if (!openQueryBtn.disabled) {
|
||||
openQueryBtn.children = [
|
||||
CommandBarComponentButtonFactory.createOpenQueryButton(container),
|
||||
CommandBarComponentButtonFactory.createOpenQueryFromDiskButton(container),
|
||||
];
|
||||
}
|
||||
|
||||
return [newSqlQueryBtn, openQueryBtn];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,581 @@
|
|||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import { Areas } from "../../../Common/Constants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
import AddDatabaseIcon from "../../../../images/AddDatabase.svg";
|
||||
import AddCollectionIcon from "../../../../images/AddCollection.svg";
|
||||
import AddSqlQueryIcon from "../../../../images/AddSqlQuery_16x16.svg";
|
||||
import BrowseQueriesIcon from "../../../../images/BrowseQuery.svg";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import OpenInTabIcon from "../../../../images/open-in-tab.svg";
|
||||
import OpenQueryFromDiskIcon from "../../../../images/OpenQueryFromDisk.svg";
|
||||
import CosmosTerminalIcon from "../../../../images/Cosmos-Terminal.svg";
|
||||
import HostedTerminalIcon from "../../../../images/Hosted-Terminal.svg";
|
||||
import AddStoredProcedureIcon from "../../../../images/AddStoredProcedure.svg";
|
||||
import SettingsIcon from "../../../../images/settings_15x15.svg";
|
||||
import AddUdfIcon from "../../../../images/AddUdf.svg";
|
||||
import AddTriggerIcon from "../../../../images/AddTrigger.svg";
|
||||
import FeedbackIcon from "../../../../images/Feedback-Command.svg";
|
||||
import EnableNotebooksIcon from "../../../../images/notebook/Notebook-enable.svg";
|
||||
import NewNotebookIcon from "../../../../images/notebook/Notebook-new.svg";
|
||||
import ResetWorkspaceIcon from "../../../../images/notebook/Notebook-reset-workspace.svg";
|
||||
import GitHubIcon from "../../../../images/github.svg";
|
||||
import SynapseIcon from "../../../../images/synapse-link.svg";
|
||||
import { configContext, Platform } from "../../../ConfigContext";
|
||||
import Explorer from "../../Explorer";
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import * as React from "react";
|
||||
import { OpenFullScreen } from "../../OpenFullScreen";
|
||||
|
||||
let counter = 0;
|
||||
|
||||
export function createStaticCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
if (container.isAuthWithResourceToken()) {
|
||||
return createStaticCommandBarButtonsForResourceToken(container);
|
||||
}
|
||||
|
||||
const newCollectionBtn = createNewCollectionGroup(container);
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
buttons.push(newCollectionBtn);
|
||||
|
||||
const addSynapseLink = createOpenSynapseLinkDialogButton(container);
|
||||
if (addSynapseLink) {
|
||||
buttons.push(createDivider());
|
||||
buttons.push(addSynapseLink);
|
||||
}
|
||||
|
||||
if (!container.isPreferredApiTable()) {
|
||||
newCollectionBtn.children = [createNewCollectionGroup(container)];
|
||||
const newDatabaseBtn = createNewDatabase(container);
|
||||
newCollectionBtn.children.push(newDatabaseBtn);
|
||||
}
|
||||
|
||||
buttons.push(createDivider());
|
||||
|
||||
if (container.isNotebookEnabled()) {
|
||||
const newNotebookButton = createNewNotebookButton(container);
|
||||
newNotebookButton.children = [createNewNotebookButton(container), createuploadNotebookButton(container)];
|
||||
buttons.push(newNotebookButton);
|
||||
|
||||
if (container.notebookManager?.gitHubOAuthService) {
|
||||
buttons.push(createManageGitHubAccountButton(container));
|
||||
}
|
||||
}
|
||||
|
||||
if (!container.isRunningOnNationalCloud()) {
|
||||
if (!container.isNotebookEnabled()) {
|
||||
buttons.push(createEnableNotebooksButton(container));
|
||||
}
|
||||
|
||||
if (container.isPreferredApiMongoDB()) {
|
||||
buttons.push(createOpenMongoTerminalButton(container));
|
||||
}
|
||||
|
||||
if (container.isPreferredApiCassandra()) {
|
||||
buttons.push(createOpenCassandraTerminalButton(container));
|
||||
}
|
||||
}
|
||||
|
||||
if (container.isNotebookEnabled()) {
|
||||
buttons.push(createOpenTerminalButton(container));
|
||||
|
||||
buttons.push(createNotebookWorkspaceResetButton(container));
|
||||
}
|
||||
|
||||
if (!container.isDatabaseNodeOrNoneSelected()) {
|
||||
if (container.isNotebookEnabled()) {
|
||||
buttons.push(createDivider());
|
||||
}
|
||||
|
||||
const isSqlQuerySupported = container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||
if (isSqlQuerySupported) {
|
||||
const newSqlQueryBtn = createNewSQLQueryButton(container);
|
||||
buttons.push(newSqlQueryBtn);
|
||||
}
|
||||
|
||||
const isSupportedOpenQueryApi =
|
||||
container.isPreferredApiDocumentDB() || container.isPreferredApiMongoDB() || container.isPreferredApiGraph();
|
||||
const isSupportedOpenQueryFromDiskApi = container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||
if (isSupportedOpenQueryApi && container.selectedNode() && container.findSelectedCollection()) {
|
||||
const openQueryBtn = createOpenQueryButton(container);
|
||||
openQueryBtn.children = [createOpenQueryButton(container), createOpenQueryFromDiskButton(container)];
|
||||
buttons.push(openQueryBtn);
|
||||
} else if (isSupportedOpenQueryFromDiskApi && container.selectedNode() && container.findSelectedCollection()) {
|
||||
buttons.push(createOpenQueryFromDiskButton(container));
|
||||
}
|
||||
|
||||
if (areScriptsSupported(container)) {
|
||||
const label = "New Stored Procedure";
|
||||
const newStoredProcedureBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddStoredProcedureIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
|
||||
newStoredProcedureBtn.children = createScriptCommandButtons(container);
|
||||
buttons.push(newStoredProcedureBtn);
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
export function createContextCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
if (!container.isDatabaseNodeOrNoneSelected() && container.isPreferredApiMongoDB()) {
|
||||
const label = "New Shell";
|
||||
const newMongoShellBtn: CommandButtonComponentProps = {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewMongoShellClick();
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected() && container.isPreferredApiMongoDB(),
|
||||
};
|
||||
buttons.push(newMongoShellBtn);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
export function createControlCommandBarButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
if (configContext.platform === Platform.Hosted) {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
if (!container.isPreferredApiCassandra()) {
|
||||
const label = "Settings";
|
||||
const settingsPaneButton: CommandButtonComponentProps = {
|
||||
iconSrc: SettingsIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.settingsPane.open(),
|
||||
commandButtonLabel: undefined,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
hasPopup: true,
|
||||
disabled: false,
|
||||
};
|
||||
buttons.push(settingsPaneButton);
|
||||
}
|
||||
|
||||
if (container.isHostedDataExplorerEnabled()) {
|
||||
const label = "Open Full Screen";
|
||||
const fullScreenButton: CommandButtonComponentProps = {
|
||||
iconSrc: OpenInTabIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
container.openSidePanel("Open Full Screen", <OpenFullScreen />);
|
||||
},
|
||||
commandButtonLabel: undefined,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
hasPopup: false,
|
||||
disabled: !container.isHostedDataExplorerEnabled(),
|
||||
className: "OpenFullScreen",
|
||||
};
|
||||
buttons.push(fullScreenButton);
|
||||
}
|
||||
|
||||
if (configContext.platform !== Platform.Emulator) {
|
||||
const label = "Feedback";
|
||||
const feedbackButtonOptions: CommandButtonComponentProps = {
|
||||
iconSrc: FeedbackIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.provideFeedbackEmail(),
|
||||
commandButtonLabel: undefined,
|
||||
ariaLabel: label,
|
||||
tooltipText: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
};
|
||||
buttons.push(feedbackButtonOptions);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
export function createDivider(): CommandButtonComponentProps {
|
||||
const label = `divider${counter++}`;
|
||||
return {
|
||||
isDivider: true,
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
iconSrc: undefined,
|
||||
iconAlt: undefined,
|
||||
onCommandClick: undefined,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function areScriptsSupported(container: Explorer): boolean {
|
||||
return container.isPreferredApiDocumentDB() || container.isPreferredApiGraph();
|
||||
}
|
||||
|
||||
function createNewCollectionGroup(container: Explorer): CommandButtonComponentProps {
|
||||
const label = container.addCollectionText();
|
||||
return {
|
||||
iconSrc: AddCollectionIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.onNewCollectionClicked(),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
id: "createNewContainerCommandButton",
|
||||
};
|
||||
}
|
||||
|
||||
function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (container.isServerlessEnabled()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (
|
||||
container.databaseAccount &&
|
||||
container.databaseAccount() &&
|
||||
container.databaseAccount().properties &&
|
||||
container.databaseAccount().properties.enableAnalyticalStorage
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const capabilities =
|
||||
(container.databaseAccount &&
|
||||
container.databaseAccount() &&
|
||||
container.databaseAccount().properties &&
|
||||
container.databaseAccount().properties.capabilities) ||
|
||||
[];
|
||||
if (capabilities.some((capability) => capability.name === Constants.CapabilityNames.EnableStorageAnalytics)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const label = "Enable Azure Synapse Link";
|
||||
return {
|
||||
iconSrc: SynapseIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.openEnableSynapseLinkDialog(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: container.isSynapseLinkUpdating(),
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function createNewDatabase(container: Explorer): CommandButtonComponentProps {
|
||||
const label = container.addDatabaseText();
|
||||
return {
|
||||
iconSrc: AddDatabaseIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
container.addDatabasePane.open();
|
||||
document.getElementById("linkAddDatabase").focus();
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
};
|
||||
}
|
||||
|
||||
function createNewSQLQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (container.isPreferredApiDocumentDB() || container.isPreferredApiGraph()) {
|
||||
const label = "New SQL Query";
|
||||
return {
|
||||
iconSrc: AddSqlQueryIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewQueryClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
} else if (container.isPreferredApiMongoDB()) {
|
||||
const label = "New Query";
|
||||
return {
|
||||
iconSrc: AddSqlQueryIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewMongoQueryClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function createScriptCommandButtons(container: Explorer): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
const shouldEnableScriptsCommands: boolean =
|
||||
!container.isDatabaseNodeOrNoneSelected() && areScriptsSupported(container);
|
||||
|
||||
if (shouldEnableScriptsCommands) {
|
||||
const label = "New Stored Procedure";
|
||||
const newStoredProcedureBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddStoredProcedureIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewStoredProcedureClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
buttons.push(newStoredProcedureBtn);
|
||||
}
|
||||
|
||||
if (shouldEnableScriptsCommands) {
|
||||
const label = "New UDF";
|
||||
const newUserDefinedFunctionBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddUdfIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewUserDefinedFunctionClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
buttons.push(newUserDefinedFunctionBtn);
|
||||
}
|
||||
|
||||
if (shouldEnableScriptsCommands) {
|
||||
const label = "New Trigger";
|
||||
const newTriggerBtn: CommandButtonComponentProps = {
|
||||
iconSrc: AddTriggerIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
const selectedCollection: ViewModels.Collection = container.findSelectedCollection();
|
||||
selectedCollection && selectedCollection.onNewTriggerClick(selectedCollection);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: container.isDatabaseNodeOrNoneSelected(),
|
||||
};
|
||||
buttons.push(newTriggerBtn);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
function createNewNotebookButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "New Notebook";
|
||||
return {
|
||||
iconSrc: NewNotebookIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.onNewNotebookClicked(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function createuploadNotebookButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Upload to Notebook Server";
|
||||
return {
|
||||
iconSrc: NewNotebookIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.onUploadToNotebookServerClicked(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function createOpenQueryButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Query";
|
||||
return {
|
||||
iconSrc: BrowseQueriesIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.browseQueriesPane.open(),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
function createOpenQueryFromDiskButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Query From Disk";
|
||||
return {
|
||||
iconSrc: OpenQueryFromDiskIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.loadQueryPane.open(),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
disabled: false,
|
||||
};
|
||||
}
|
||||
|
||||
function createEnableNotebooksButton(container: Explorer): CommandButtonComponentProps {
|
||||
if (configContext.platform === Platform.Emulator) {
|
||||
return undefined;
|
||||
}
|
||||
const label = "Enable Notebooks (Preview)";
|
||||
const tooltip =
|
||||
"Notebooks are not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||
const description =
|
||||
"Looks like you have not yet created a notebooks workspace for this account. To proceed and start using notebooks, we'll need to create a default notebooks workspace in this account.";
|
||||
return {
|
||||
iconSrc: EnableNotebooksIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.setupNotebooksPane.openWithTitleAndDescription(label, description),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: !container.isNotebooksEnabledForAccount(),
|
||||
ariaLabel: label,
|
||||
tooltipText: container.isNotebooksEnabledForAccount() ? "" : tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
function createOpenTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Terminal";
|
||||
return {
|
||||
iconSrc: CosmosTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.openNotebookTerminal(ViewModels.TerminalKind.Default),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function createOpenMongoTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Mongo Shell";
|
||||
const tooltip =
|
||||
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||
const title = "Set up workspace";
|
||||
const description =
|
||||
"Looks like you have not created a workspace for this account. To proceed and start using features including mongo shell and notebook, we will need to create a default workspace in this account.";
|
||||
const disableButton = !container.isNotebooksEnabledForAccount() && !container.isNotebookEnabled();
|
||||
return {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (container.isNotebookEnabled()) {
|
||||
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
|
||||
} else {
|
||||
container.setupNotebooksPane.openWithTitleAndDescription(title, description);
|
||||
}
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: disableButton,
|
||||
ariaLabel: label,
|
||||
tooltipText: !disableButton ? "" : tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
function createOpenCassandraTerminalButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Open Cassandra Shell";
|
||||
const tooltip =
|
||||
"This feature is not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
|
||||
const title = "Set up workspace";
|
||||
const description =
|
||||
"Looks like you have not created a workspace for this account. To proceed and start using features including cassandra shell and notebook, we will need to create a default workspace in this account.";
|
||||
const disableButton = !container.isNotebooksEnabledForAccount() && !container.isNotebookEnabled();
|
||||
return {
|
||||
iconSrc: HostedTerminalIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (container.isNotebookEnabled()) {
|
||||
container.openNotebookTerminal(ViewModels.TerminalKind.Cassandra);
|
||||
} else {
|
||||
container.setupNotebooksPane.openWithTitleAndDescription(title, description);
|
||||
}
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: disableButton,
|
||||
ariaLabel: label,
|
||||
tooltipText: !disableButton ? "" : tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
function createNotebookWorkspaceResetButton(container: Explorer): CommandButtonComponentProps {
|
||||
const label = "Reset Workspace";
|
||||
return {
|
||||
iconSrc: ResetWorkspaceIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => container.resetNotebookWorkspace(),
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function createManageGitHubAccountButton(container: Explorer): CommandButtonComponentProps {
|
||||
const connectedToGitHub: boolean = container.notebookManager?.gitHubOAuthService.isLoggedIn();
|
||||
const label = connectedToGitHub ? "Manage GitHub settings" : "Connect to GitHub";
|
||||
return {
|
||||
iconSrc: GitHubIcon,
|
||||
iconAlt: label,
|
||||
onCommandClick: () => {
|
||||
if (!connectedToGitHub) {
|
||||
TelemetryProcessor.trace(Action.NotebooksGitHubConnect, ActionModifiers.Mark, {
|
||||
databaseAccountName: container.databaseAccount() && container.databaseAccount().name,
|
||||
defaultExperience: container.defaultExperience && container.defaultExperience(),
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
}
|
||||
container.gitHubReposPane.open();
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
ariaLabel: label,
|
||||
};
|
||||
}
|
||||
|
||||
function createStaticCommandBarButtonsForResourceToken(container: Explorer): CommandButtonComponentProps[] {
|
||||
const newSqlQueryBtn = createNewSQLQueryButton(container);
|
||||
const openQueryBtn = createOpenQueryButton(container);
|
||||
|
||||
newSqlQueryBtn.disabled = !container.isResourceTokenCollectionNodeSelected();
|
||||
newSqlQueryBtn.onCommandClick = () => {
|
||||
const resourceTokenCollection: ViewModels.CollectionBase = container.resourceTokenCollection();
|
||||
resourceTokenCollection && resourceTokenCollection.onNewQueryClick(resourceTokenCollection, undefined);
|
||||
};
|
||||
|
||||
openQueryBtn.disabled = !container.isResourceTokenCollectionNodeSelected();
|
||||
if (!openQueryBtn.disabled) {
|
||||
openQueryBtn.children = [createOpenQueryButton(container), createOpenQueryFromDiskButton(container)];
|
||||
}
|
||||
|
||||
return [newSqlQueryBtn, openQueryBtn];
|
||||
}
|
|
@ -20,7 +20,6 @@ describe("OpenActions", () => {
|
|||
explorer.cassandraAddCollectionPane = {} as CassandraAddCollectionPane;
|
||||
explorer.cassandraAddCollectionPane.open = jest.fn();
|
||||
explorer.closeAllPanes = () => {};
|
||||
explorer.isConnectExplorerVisible = () => false;
|
||||
|
||||
database = {
|
||||
id: ko.observable("db"),
|
||||
|
|
|
@ -133,19 +133,19 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
|
|||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.AddCollection]
|
||||
) {
|
||||
explorer.closeAllPanes();
|
||||
!explorer.isConnectExplorerVisible() && explorer.addCollectionPane.open();
|
||||
explorer.addCollectionPane.open();
|
||||
} else if (
|
||||
action.paneKind === ActionContracts.PaneKind.CassandraAddCollection ||
|
||||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.CassandraAddCollection]
|
||||
) {
|
||||
explorer.closeAllPanes();
|
||||
!explorer.isConnectExplorerVisible() && explorer.cassandraAddCollectionPane.open();
|
||||
explorer.cassandraAddCollectionPane.open();
|
||||
} else if (
|
||||
action.paneKind === ActionContracts.PaneKind.GlobalSettings ||
|
||||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.GlobalSettings]
|
||||
) {
|
||||
explorer.closeAllPanes();
|
||||
!explorer.isConnectExplorerVisible() && explorer.settingsPane.open();
|
||||
explorer.settingsPane.open();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
jest.mock("../hooks/useFullScreenURLs");
|
||||
import "@testing-library/jest-dom";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import { useFullScreenURLs } from "../hooks/useFullScreenURLs";
|
||||
import { OpenFullScreen } from "./OpenFullScreen";
|
||||
|
||||
it("renders the correct URLs", () => {
|
||||
(useFullScreenURLs as jest.Mock).mockReturnValue({
|
||||
readWrite: "read and write url",
|
||||
read: "read only url",
|
||||
});
|
||||
|
||||
render(<OpenFullScreen />);
|
||||
expect(screen.getByLabelText("Read and Write")).toHaveValue("https://cosmos.azure.com/?key=read and write url");
|
||||
expect(screen.getByLabelText("Read Only")).toHaveValue("https://cosmos.azure.com/?key=read only url");
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
import { Spinner, Stack, Text, TextField } from "office-ui-fabric-react";
|
||||
import { DefaultButton, PrimaryButton } from "office-ui-fabric-react/lib/Button";
|
||||
import * as React from "react";
|
||||
import { useFullScreenURLs } from "../hooks/useFullScreenURLs";
|
||||
import copyToClipboard from "clipboard-copy";
|
||||
|
||||
export const OpenFullScreen: React.FunctionComponent = () => {
|
||||
const result = useFullScreenURLs();
|
||||
if (!result) {
|
||||
return <Spinner label="Generating URLs..." ariaLive="assertive" labelPosition="right" />;
|
||||
}
|
||||
|
||||
const readWriteUrl = `https://cosmos.azure.com/?key=${result.readWrite}`;
|
||||
const readUrl = `https://cosmos.azure.com/?key=${result.read}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack tokens={{ childrenGap: 10 }}>
|
||||
<Text>
|
||||
Open this database account in a new browser tab with Cosmos DB Explorer. Or copy the read-write or read only
|
||||
access urls below to share with others. For security purposes, the URLs grant time-bound access to the
|
||||
account. When access expires, you can reconnect, using a valid connection string for the account.
|
||||
</Text>
|
||||
<TextField label="Read and Write" readOnly defaultValue={readWriteUrl} />
|
||||
<Stack horizontal tokens={{ childrenGap: 10 }}>
|
||||
<DefaultButton
|
||||
onClick={() => {
|
||||
copyToClipboard(readWriteUrl);
|
||||
}}
|
||||
text="Copy"
|
||||
iconProps={{ iconName: "Copy" }}
|
||||
/>
|
||||
<PrimaryButton
|
||||
onClick={() => {
|
||||
window.open(readWriteUrl, "_blank");
|
||||
}}
|
||||
text="Open"
|
||||
iconProps={{ iconName: "OpenInNewWindow" }}
|
||||
/>
|
||||
</Stack>
|
||||
<TextField label="Read Only" readOnly defaultValue={readUrl} />
|
||||
<Stack horizontal tokens={{ childrenGap: 10 }}>
|
||||
<DefaultButton
|
||||
onClick={() => {
|
||||
copyToClipboard(readUrl);
|
||||
}}
|
||||
text="Copy"
|
||||
iconProps={{ iconName: "Copy" }}
|
||||
/>
|
||||
<PrimaryButton
|
||||
onClick={() => {
|
||||
window.open(readUrl, "_blank");
|
||||
}}
|
||||
text="Open"
|
||||
iconProps={{ iconName: "OpenInNewWindow" }}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -20,7 +20,7 @@ import KillKernelIcon from "../../../images/notebook/Notebook-stop.svg";
|
|||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { Action, ActionModifiers, Source } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import { Areas, ArmApiVersions } from "../../Common/Constants";
|
||||
import { CommandBarComponentButtonFactory } from "../Menus/CommandBar/CommandBarComponentButtonFactory";
|
||||
import * as CommandBarComponentButtonFactory from "../Menus/CommandBar/CommandBarComponentButtonFactory";
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
|
||||
import { NotebookComponentAdapter } from "../Notebook/NotebookComponent/NotebookComponentAdapter";
|
||||
|
|
68
src/Main.tsx
68
src/Main.tsx
|
@ -58,7 +58,6 @@ import { initializeIcons } from "office-ui-fabric-react/lib/Icons";
|
|||
import { ExplorerParams } from "./Explorer/Explorer";
|
||||
import React, { useState } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import copyImage from "../images/Copy.svg";
|
||||
import hdeConnectImage from "../images/HdeConnectCosmosDB.svg";
|
||||
import refreshImg from "../images/refresh-cosmos.svg";
|
||||
import arrowLeftImg from "../images/imgarrowlefticon.svg";
|
||||
|
@ -117,74 +116,7 @@ const App: React.FunctionComponent = () => {
|
|||
className="flexContainer hideOverflows"
|
||||
style={{ display: "none" }}
|
||||
>
|
||||
{/* Main Command Bar - Start */}
|
||||
<div data-bind="react: commandBarComponentAdapter" />
|
||||
{/* Main Command Bar - End */}
|
||||
{/* Share url flyout - Start */}
|
||||
<div
|
||||
id="shareDataAccessFlyout"
|
||||
className="shareDataAccessFlyout"
|
||||
data-bind="visible: shouldShowShareDialogContents"
|
||||
>
|
||||
<div className="shareDataAccessFlyoutContent">
|
||||
<div className="urlContainer">
|
||||
<span className="urlContentText">
|
||||
Open this database account in a new browser tab with Cosmos DB Explorer. Or copy the read-write or read
|
||||
only access urls below to share with others. For security purposes, the URLs grant time-bound access to
|
||||
the account. When access expires, you can reconnect, using a valid connection string for the account.
|
||||
</span>
|
||||
<br />
|
||||
<div
|
||||
className="toggles"
|
||||
data-bind="event: { keydown: onToggleKeyDown }, visible: shareAccessData().readWriteUrl != null"
|
||||
tabIndex={0}
|
||||
aria-label="Read-Write and Read toggle"
|
||||
>
|
||||
<div className="tab">
|
||||
<input type="radio" className="radio" defaultValue="readwrite" />
|
||||
<span
|
||||
className="toggleSwitch"
|
||||
role="presentation"
|
||||
data-bind="click: toggleReadWrite, css:{ selectedToggle: isReadWriteToggled(), unselectedToggle: !isReadWriteToggled() }"
|
||||
>
|
||||
Read-Write
|
||||
</span>
|
||||
</div>
|
||||
<div className="tab">
|
||||
<input type="radio" className="radio" defaultValue="read" />
|
||||
<span
|
||||
className="toggleSwitch"
|
||||
role="presentation"
|
||||
data-bind="click: toggleRead, css:{ selectedToggle: isReadToggled(), unselectedToggle: !isReadToggled() }"
|
||||
>
|
||||
Read
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="urlSpace">
|
||||
<input
|
||||
id="shareUrlLink"
|
||||
aria-label="Share url link"
|
||||
className="shareLink"
|
||||
type="text"
|
||||
read-only={true}
|
||||
data-bind="value: shareAccessUrl"
|
||||
/>
|
||||
<span
|
||||
className="urlTokenCopyInfoTooltip"
|
||||
data-bind="click: copyUrlLink, event: { keypress: onCopyUrlLinkKeyPress }"
|
||||
aria-label="Copy url link"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
>
|
||||
<img src={copyImage} alt="Copy link" />
|
||||
<span className="urlTokenCopyTooltiptext" data-bind="text: shareUrlCopyHelperText" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Share url flyout - End */}
|
||||
{/* Collections Tree and Tabs - Begin */}
|
||||
<div className="resourceTreeAndTabs">
|
||||
{/* Collections Tree - Start */}
|
||||
|
|
|
@ -6,39 +6,15 @@ import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"
|
|||
import { userContext } from "../../UserContext";
|
||||
|
||||
export default class AuthHeadersUtil {
|
||||
public static generateEncryptedToken(): Q.Promise<DataModels.GenerateTokenResponse> {
|
||||
public static async generateEncryptedToken(readOnly: boolean = false): Promise<DataModels.GenerateTokenResponse> {
|
||||
const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + AuthHeadersUtil._generateResourceUrl();
|
||||
const explorer = window.dataExplorer;
|
||||
const headers: any = { authorization: userContext.authorizationToken };
|
||||
headers[Constants.HttpHeaders.getReadOnlyKey] = !explorer.hasWriteAccess();
|
||||
headers[Constants.HttpHeaders.getReadOnlyKey] = readOnly;
|
||||
|
||||
return AuthHeadersUtil._initiateGenerateTokenRequest({
|
||||
url: url,
|
||||
type: "POST",
|
||||
headers: headers,
|
||||
contentType: "application/json",
|
||||
cache: false,
|
||||
});
|
||||
}
|
||||
|
||||
public static generateUnauthenticatedEncryptedTokenForConnectionString(
|
||||
connectionString: string
|
||||
): Q.Promise<DataModels.GenerateTokenResponse> {
|
||||
if (!connectionString) {
|
||||
return Q.reject("None or empty connection string specified");
|
||||
}
|
||||
|
||||
const url = configContext.BACKEND_ENDPOINT + "/api/guest/tokens/generateToken";
|
||||
const headers: any = {};
|
||||
headers[Constants.HttpHeaders.connectionString] = connectionString;
|
||||
|
||||
return AuthHeadersUtil._initiateGenerateTokenRequest({
|
||||
url: url,
|
||||
type: "POST",
|
||||
headers: headers,
|
||||
contentType: "application/json",
|
||||
cache: false,
|
||||
});
|
||||
const response = await fetch(url, { method: "POST", headers });
|
||||
const result = await response.json();
|
||||
// This API has a quirk where the response must be parsed to JSON twice
|
||||
return JSON.parse(result);
|
||||
}
|
||||
|
||||
private static _generateResourceUrl(): string {
|
||||
|
@ -56,25 +32,4 @@ export default class AuthHeadersUtil {
|
|||
const rtype = "";
|
||||
return `?resourceUrl=${resourceUrl}&rid=${rid}&rtype=${rtype}&sid=${sid}&rg=${rg}&dba=${dba}&api=${apiKind}`;
|
||||
}
|
||||
|
||||
private static _initiateGenerateTokenRequest(
|
||||
requestSettings: JQueryAjaxSettings<any>
|
||||
): Q.Promise<DataModels.GenerateTokenResponse> {
|
||||
const deferred: Q.Deferred<DataModels.GenerateTokenResponse> = Q.defer<DataModels.GenerateTokenResponse>();
|
||||
|
||||
$.ajax(requestSettings).then(
|
||||
(data: string, textStatus: string, xhr: JQueryXHR<any>) => {
|
||||
if (!data) {
|
||||
deferred.reject("No token generated");
|
||||
}
|
||||
|
||||
deferred.resolve(JSON.parse(data));
|
||||
},
|
||||
(xhr: JQueryXHR<any>, textStatus: string, error: any) => {
|
||||
deferred.reject(xhr.responseText);
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.promise.timeout(Constants.ClientDefaults.requestTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { GenerateTokenResponse } from "../Contracts/DataModels";
|
||||
import AuthHeadersUtil from "../Platform/Hosted/Authorization";
|
||||
|
||||
export function useFullScreenURLs(): GenerateTokenResponse | undefined {
|
||||
const [state, setState] = useState<GenerateTokenResponse>();
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all([AuthHeadersUtil.generateEncryptedToken(), AuthHeadersUtil.generateEncryptedToken(true)]).then(
|
||||
([readWriteResponse, readOnlyResponse]) =>
|
||||
setState({
|
||||
readWrite: readWriteResponse.readWrite,
|
||||
read: readOnlyResponse.read,
|
||||
})
|
||||
);
|
||||
}, []);
|
||||
return state;
|
||||
}
|
Loading…
Reference in New Issue