mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 17:01:13 +00:00
Migrated Hosted Explorer to React (#360)
Co-authored-by: Victor Meng <vimeng@microsoft.com> Co-authored-by: Steve Faulkner <stfaul@microsoft.com>
This commit is contained in:
@@ -1,159 +0,0 @@
|
||||
import React from "react";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import { AccountSwitchComponent, AccountSwitchComponentProps } from "./AccountSwitchComponent";
|
||||
import { AuthType } from "../../../AuthType";
|
||||
import { DatabaseAccount, Subscription } from "../../../Contracts/DataModels";
|
||||
import { AccountKind } from "../../../Common/Constants";
|
||||
|
||||
const createBlankProps = (): AccountSwitchComponentProps => {
|
||||
return {
|
||||
authType: null,
|
||||
displayText: "",
|
||||
accounts: [],
|
||||
selectedAccountName: null,
|
||||
isLoadingAccounts: false,
|
||||
onAccountChange: jest.fn(),
|
||||
subscriptions: [],
|
||||
selectedSubscriptionId: null,
|
||||
isLoadingSubscriptions: false,
|
||||
onSubscriptionChange: jest.fn()
|
||||
};
|
||||
};
|
||||
|
||||
const createBlankAccount = (): DatabaseAccount => {
|
||||
return {
|
||||
id: "",
|
||||
kind: AccountKind.Default,
|
||||
name: "",
|
||||
properties: null,
|
||||
location: "",
|
||||
tags: null,
|
||||
type: ""
|
||||
};
|
||||
};
|
||||
|
||||
const createBlankSubscription = (): Subscription => {
|
||||
return {
|
||||
subscriptionId: "",
|
||||
displayName: "",
|
||||
authorizationSource: "",
|
||||
state: "",
|
||||
subscriptionPolicies: null,
|
||||
tenantId: "",
|
||||
uniqueDisplayName: ""
|
||||
};
|
||||
};
|
||||
|
||||
const createFullProps = (): AccountSwitchComponentProps => {
|
||||
const props = createBlankProps();
|
||||
props.authType = AuthType.AAD;
|
||||
const account1 = createBlankAccount();
|
||||
account1.name = "account1";
|
||||
const account2 = createBlankAccount();
|
||||
account2.name = "account2";
|
||||
const account3 = createBlankAccount();
|
||||
account3.name = "superlongaccountnamestringtest";
|
||||
props.accounts = [account1, account2, account3];
|
||||
props.selectedAccountName = "account2";
|
||||
|
||||
const sub1 = createBlankSubscription();
|
||||
sub1.displayName = "sub1";
|
||||
sub1.subscriptionId = "a6062a74-5d53-4b20-9545-000b95f22297";
|
||||
const sub2 = createBlankSubscription();
|
||||
sub2.displayName = "subsubsubsubsubsubsub2";
|
||||
sub2.subscriptionId = "b20b3e93-0185-4326-8a9c-d44bac276b6b";
|
||||
props.subscriptions = [sub1, sub2];
|
||||
props.selectedSubscriptionId = "a6062a74-5d53-4b20-9545-000b95f22297";
|
||||
|
||||
return props;
|
||||
};
|
||||
|
||||
describe("test render", () => {
|
||||
it("renders no auth type -> handle error in code", () => {
|
||||
const props = createBlankProps();
|
||||
|
||||
const wrapper = shallow(<AccountSwitchComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// Encrypted Token
|
||||
it("renders auth security token, with selected account name", () => {
|
||||
const props = createBlankProps();
|
||||
props.authType = AuthType.EncryptedToken;
|
||||
props.selectedAccountName = "testaccount";
|
||||
|
||||
const wrapper = shallow(<AccountSwitchComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// AAD
|
||||
it("renders auth aad, with all information", () => {
|
||||
const props = createFullProps();
|
||||
const wrapper = shallow(<AccountSwitchComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders auth aad all dropdown menus", () => {
|
||||
const props = createFullProps();
|
||||
const wrapper = mount(<AccountSwitchComponent {...props} />);
|
||||
|
||||
expect(wrapper.exists("div.accountSwitchContextualMenu")).toBe(false);
|
||||
wrapper.find("button.accountSwitchButton").simulate("click");
|
||||
expect(wrapper.exists("div.accountSwitchContextualMenu")).toBe(true);
|
||||
|
||||
expect(wrapper.exists("div.accountSwitchSubscriptionDropdown")).toBe(true);
|
||||
wrapper.find("DropdownBase.accountSwitchSubscriptionDropdown").simulate("click");
|
||||
// Click will dismiss the first contextual menu in enzyme. Need to dig deeper to achieve below test
|
||||
|
||||
// expect(wrapper.exists("div.accountSwitchSubscriptionDropdownMenu")).toBe(true);
|
||||
// expect(wrapper.find("button.ms-Dropdown-item").length).toBe(2);
|
||||
// wrapper.find("div.accountSwitchSubscriptionDropdown").simulate("click");
|
||||
// expect(wrapper.exists("div.accountSwitchSubscriptionDropdownMenu")).toBe(false);
|
||||
|
||||
// expect(wrapper.exists("div.accountSwitchAccountDropdown")).toBe(true);
|
||||
// wrapper.find("div.accountSwitchAccountDropdown").simulate("click");
|
||||
// expect(wrapper.exists("div.accountSwitchAccountDropdownMenu")).toBe(true);
|
||||
// expect(wrapper.find("button.ms-Dropdown-item").length).toBe(3);
|
||||
// wrapper.find("div.accountSwitchAccountDropdown").simulate("click");
|
||||
// expect(wrapper.exists("div.accountSwitchAccountDropdownMenu")).toBe(false);
|
||||
|
||||
// wrapper.find("button.accountSwitchButton").simulate("click");
|
||||
// expect(wrapper.exists("div.accountSwitchContextualMenu")).toBe(false);
|
||||
|
||||
wrapper.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
// describe("test function", () => {
|
||||
// it("switch subscription function", () => {
|
||||
// const props = createFullProps();
|
||||
// const wrapper = mount(<AccountSwitchComponent {...props} />);
|
||||
|
||||
// wrapper.find("button.accountSwitchButton").simulate("click");
|
||||
// wrapper.find("div.accountSwitchSubscriptionDropdown").simulate("click");
|
||||
// wrapper
|
||||
// .find("button.ms-Dropdown-item")
|
||||
// .at(1)
|
||||
// .simulate("click");
|
||||
// expect(props.onSubscriptionChange).toBeCalled();
|
||||
// expect(props.onSubscriptionChange).toHaveBeenCalled();
|
||||
|
||||
// wrapper.unmount();
|
||||
// });
|
||||
|
||||
// it("switch account", () => {
|
||||
// const props = createFullProps();
|
||||
// const wrapper = mount(<AccountSwitchComponent {...props} />);
|
||||
|
||||
// wrapper.find("button.accountSwitchButton").simulate("click");
|
||||
// wrapper.find("div.accountSwitchAccountDropdown").simulate("click");
|
||||
// wrapper
|
||||
// .find("button.ms-Dropdown-item")
|
||||
// .at(0)
|
||||
// .simulate("click");
|
||||
// expect(props.onAccountChange).toBeCalled();
|
||||
// expect(props.onAccountChange).toHaveBeenCalled();
|
||||
|
||||
// wrapper.unmount();
|
||||
// });
|
||||
// });
|
||||
@@ -1,177 +0,0 @@
|
||||
import { AuthType } from "../../../AuthType";
|
||||
import { StyleConstants } from "../../../Common/Constants";
|
||||
import { DatabaseAccount, Subscription } from "../../../Contracts/DataModels";
|
||||
|
||||
import * as React from "react";
|
||||
import { DefaultButton, IButtonStyles, IButtonProps } from "office-ui-fabric-react/lib/Button";
|
||||
import { IContextualMenuProps } from "office-ui-fabric-react/lib/ContextualMenu";
|
||||
import { Dropdown, IDropdownOption, IDropdownProps } from "office-ui-fabric-react/lib/Dropdown";
|
||||
|
||||
export interface AccountSwitchComponentProps {
|
||||
authType: AuthType;
|
||||
selectedAccountName: string;
|
||||
accounts: DatabaseAccount[];
|
||||
isLoadingAccounts: boolean;
|
||||
onAccountChange: (newAccount: DatabaseAccount) => void;
|
||||
selectedSubscriptionId: string;
|
||||
subscriptions: Subscription[];
|
||||
isLoadingSubscriptions: boolean;
|
||||
onSubscriptionChange: (newSubscription: Subscription) => void;
|
||||
displayText?: string;
|
||||
}
|
||||
|
||||
export class AccountSwitchComponent extends React.Component<AccountSwitchComponentProps> {
|
||||
public render(): JSX.Element {
|
||||
return this.props.authType === AuthType.AAD ? this._renderSwitchDropDown() : this._renderAccountName();
|
||||
}
|
||||
|
||||
private _renderSwitchDropDown(): JSX.Element {
|
||||
const { displayText, selectedAccountName } = this.props;
|
||||
|
||||
const menuProps: IContextualMenuProps = {
|
||||
directionalHintFixed: true,
|
||||
className: "accountSwitchContextualMenu",
|
||||
items: [
|
||||
{
|
||||
key: "switchSubscription",
|
||||
onRender: this._renderSubscriptionDropdown.bind(this)
|
||||
},
|
||||
{
|
||||
key: "switchAccount",
|
||||
onRender: this._renderAccountDropDown.bind(this)
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const buttonStyles: IButtonStyles = {
|
||||
root: {
|
||||
fontSize: StyleConstants.DefaultFontSize,
|
||||
height: 40,
|
||||
padding: 0,
|
||||
paddingLeft: 10,
|
||||
marginRight: 5,
|
||||
backgroundColor: StyleConstants.BaseDark,
|
||||
color: StyleConstants.BaseLight
|
||||
},
|
||||
rootHovered: {
|
||||
backgroundColor: StyleConstants.BaseHigh,
|
||||
color: StyleConstants.BaseLight
|
||||
},
|
||||
rootFocused: {
|
||||
backgroundColor: StyleConstants.BaseHigh,
|
||||
color: StyleConstants.BaseLight
|
||||
},
|
||||
rootPressed: {
|
||||
backgroundColor: StyleConstants.BaseHigh,
|
||||
color: StyleConstants.BaseLight
|
||||
},
|
||||
rootExpanded: {
|
||||
backgroundColor: StyleConstants.BaseHigh,
|
||||
color: StyleConstants.BaseLight
|
||||
},
|
||||
textContainer: {
|
||||
flexGrow: "initial"
|
||||
}
|
||||
};
|
||||
|
||||
const buttonProps: IButtonProps = {
|
||||
text: displayText || selectedAccountName,
|
||||
menuProps: menuProps,
|
||||
styles: buttonStyles,
|
||||
className: "accountSwitchButton",
|
||||
id: "accountSwitchButton"
|
||||
};
|
||||
|
||||
return <DefaultButton {...buttonProps} />;
|
||||
}
|
||||
|
||||
private _renderSubscriptionDropdown(): JSX.Element {
|
||||
const { subscriptions, selectedSubscriptionId, isLoadingSubscriptions } = this.props;
|
||||
const options: IDropdownOption[] = subscriptions.map(sub => {
|
||||
return {
|
||||
key: sub.subscriptionId,
|
||||
text: sub.displayName,
|
||||
data: sub
|
||||
};
|
||||
});
|
||||
|
||||
const placeHolderText = isLoadingSubscriptions
|
||||
? "Loading subscriptions"
|
||||
: !options || !options.length
|
||||
? "No subscriptions found in current directory"
|
||||
: "Select subscription from list";
|
||||
|
||||
const dropdownProps: IDropdownProps = {
|
||||
label: "Subscription",
|
||||
className: "accountSwitchSubscriptionDropdown",
|
||||
options: options,
|
||||
onChange: this._onSubscriptionDropdownChange,
|
||||
defaultSelectedKey: selectedSubscriptionId,
|
||||
placeholder: placeHolderText,
|
||||
styles: {
|
||||
callout: "accountSwitchSubscriptionDropdownMenu"
|
||||
}
|
||||
};
|
||||
|
||||
return <Dropdown {...dropdownProps} />;
|
||||
}
|
||||
|
||||
private _onSubscriptionDropdownChange = (e: React.FormEvent<HTMLDivElement>, option: IDropdownOption): void => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onSubscriptionChange(option.data);
|
||||
};
|
||||
|
||||
private _renderAccountDropDown(): JSX.Element {
|
||||
const { accounts, selectedAccountName, isLoadingAccounts } = this.props;
|
||||
const options: IDropdownOption[] = accounts.map(account => {
|
||||
return {
|
||||
key: account.name,
|
||||
text: account.name,
|
||||
data: account
|
||||
};
|
||||
});
|
||||
// Fabric UI will also try to select the first non-disabled option from dropdown.
|
||||
// Add a option to prevent pop the message when user click on dropdown on first time.
|
||||
options.unshift({
|
||||
key: "select from list",
|
||||
text: "Select Cosmos DB account from list",
|
||||
data: undefined
|
||||
});
|
||||
|
||||
const placeHolderText = isLoadingAccounts
|
||||
? "Loading Cosmos DB accounts"
|
||||
: !options || !options.length
|
||||
? "No Cosmos DB accounts found"
|
||||
: "Select Cosmos DB account from list";
|
||||
|
||||
const dropdownProps: IDropdownProps = {
|
||||
label: "Cosmos DB Account Name",
|
||||
className: "accountSwitchAccountDropdown",
|
||||
options: options,
|
||||
onChange: this._onAccountDropdownChange,
|
||||
defaultSelectedKey: selectedAccountName,
|
||||
placeholder: placeHolderText,
|
||||
styles: {
|
||||
callout: "accountSwitchAccountDropdownMenu"
|
||||
}
|
||||
};
|
||||
|
||||
return <Dropdown {...dropdownProps} />;
|
||||
}
|
||||
|
||||
private _onAccountDropdownChange = (e: React.FormEvent<HTMLDivElement>, option: IDropdownOption): void => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onAccountChange(option.data);
|
||||
};
|
||||
|
||||
private _renderAccountName(): JSX.Element {
|
||||
const { displayText, selectedAccountName } = this.props;
|
||||
return <span className="accountNameHeader">{displayText || selectedAccountName}</span>;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||
import { AccountSwitchComponent, AccountSwitchComponentProps } from "./AccountSwitchComponent";
|
||||
|
||||
export class AccountSwitchComponentAdapter implements ReactAdapter {
|
||||
public parameters: ko.Observable<AccountSwitchComponentProps>;
|
||||
|
||||
public renderComponent(): JSX.Element {
|
||||
return <AccountSwitchComponent {...this.parameters()} />;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`test render renders auth aad, with all information 1`] = `
|
||||
<CustomizedDefaultButton
|
||||
className="accountSwitchButton"
|
||||
id="accountSwitchButton"
|
||||
menuProps={
|
||||
Object {
|
||||
"className": "accountSwitchContextualMenu",
|
||||
"directionalHintFixed": true,
|
||||
"items": Array [
|
||||
Object {
|
||||
"key": "switchSubscription",
|
||||
"onRender": [Function],
|
||||
},
|
||||
Object {
|
||||
"key": "switchAccount",
|
||||
"onRender": [Function],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
styles={
|
||||
Object {
|
||||
"root": Object {
|
||||
"backgroundColor": undefined,
|
||||
"color": undefined,
|
||||
"fontSize": undefined,
|
||||
"height": 40,
|
||||
"marginRight": 5,
|
||||
"padding": 0,
|
||||
"paddingLeft": 10,
|
||||
},
|
||||
"rootExpanded": Object {
|
||||
"backgroundColor": undefined,
|
||||
"color": undefined,
|
||||
},
|
||||
"rootFocused": Object {
|
||||
"backgroundColor": undefined,
|
||||
"color": undefined,
|
||||
},
|
||||
"rootHovered": Object {
|
||||
"backgroundColor": undefined,
|
||||
"color": undefined,
|
||||
},
|
||||
"rootPressed": Object {
|
||||
"backgroundColor": undefined,
|
||||
"color": undefined,
|
||||
},
|
||||
"textContainer": Object {
|
||||
"flexGrow": "initial",
|
||||
},
|
||||
}
|
||||
}
|
||||
text="account2"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`test render renders auth security token, with selected account name 1`] = `
|
||||
<span
|
||||
className="accountNameHeader"
|
||||
>
|
||||
testaccount
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`test render renders no auth type -> handle error in code 1`] = `
|
||||
<span
|
||||
className="accountNameHeader"
|
||||
/>
|
||||
`;
|
||||
@@ -38,7 +38,7 @@ export interface CommandButtonComponentProps {
|
||||
/**
|
||||
* Label for the button
|
||||
*/
|
||||
commandButtonLabel: string;
|
||||
commandButtonLabel?: string;
|
||||
|
||||
/**
|
||||
* True if this button opens a tab or pane, false otherwise.
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
getSanitizedInputValue,
|
||||
hasDatabaseSharedThroughput,
|
||||
isDirty,
|
||||
isDirtyTypes,
|
||||
MongoIndexTypes,
|
||||
MongoNotificationType,
|
||||
parseConflictResolutionMode,
|
||||
@@ -71,17 +70,18 @@ describe("SettingsUtils", () => {
|
||||
excludedPaths: []
|
||||
} as DataModels.IndexingPolicy;
|
||||
|
||||
const cases = [
|
||||
["baseline", "current"],
|
||||
[0, 1],
|
||||
[true, false],
|
||||
[undefined, indexingPolicy],
|
||||
[indexingPolicy, { ...indexingPolicy, automatic: false }]
|
||||
];
|
||||
it("works on all types", () => {
|
||||
expect(isDirty("baseline", "baseline")).toEqual(false);
|
||||
expect(isDirty(0, 0)).toEqual(false);
|
||||
expect(isDirty(true, true)).toEqual(false);
|
||||
expect(isDirty(undefined, undefined)).toEqual(false);
|
||||
expect(isDirty(indexingPolicy, indexingPolicy)).toEqual(false);
|
||||
|
||||
test.each(cases)("", (baseline: isDirtyTypes, current: isDirtyTypes) => {
|
||||
expect(isDirty(baseline, baseline)).toEqual(false);
|
||||
expect(isDirty(baseline, current)).toEqual(true);
|
||||
expect(isDirty("baseline", "current")).toEqual(true);
|
||||
expect(isDirty(0, 1)).toEqual(true);
|
||||
expect(isDirty(true, false)).toEqual(true);
|
||||
expect(isDirty(undefined, indexingPolicy)).toEqual(true);
|
||||
expect(isDirty(indexingPolicy, { ...indexingPolicy, automatic: false })).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1026,7 +1026,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"notificationConsoleData": [Function],
|
||||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"provideFeedbackEmail": [Function],
|
||||
"queriesClient": QueriesClient {
|
||||
@@ -1072,8 +1071,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
@@ -1166,7 +1163,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"shouldShowContextSwitchPrompt": [Function],
|
||||
"shouldShowDataAccessExpiryDialog": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splashScreenAdapter": SplashScreenComponentAdapter {
|
||||
"clearMostRecent": [Function],
|
||||
@@ -1233,7 +1229,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
@@ -2301,7 +2296,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"notificationConsoleData": [Function],
|
||||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"provideFeedbackEmail": [Function],
|
||||
"queriesClient": QueriesClient {
|
||||
@@ -2347,8 +2341,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
@@ -2441,7 +2433,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"shouldShowContextSwitchPrompt": [Function],
|
||||
"shouldShowDataAccessExpiryDialog": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splashScreenAdapter": SplashScreenComponentAdapter {
|
||||
"clearMostRecent": [Function],
|
||||
@@ -2508,7 +2499,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
@@ -3589,7 +3579,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"notificationConsoleData": [Function],
|
||||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"provideFeedbackEmail": [Function],
|
||||
"queriesClient": QueriesClient {
|
||||
@@ -3635,8 +3624,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
@@ -3729,7 +3716,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"shouldShowContextSwitchPrompt": [Function],
|
||||
"shouldShowDataAccessExpiryDialog": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splashScreenAdapter": SplashScreenComponentAdapter {
|
||||
"clearMostRecent": [Function],
|
||||
@@ -3796,7 +3782,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
@@ -4864,7 +4849,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"notificationConsoleData": [Function],
|
||||
"onRefreshDatabasesKeyPress": [Function],
|
||||
"onRefreshResourcesClick": [Function],
|
||||
"onSwitchToConnectionString": [Function],
|
||||
"onToggleKeyDown": [Function],
|
||||
"provideFeedbackEmail": [Function],
|
||||
"queriesClient": QueriesClient {
|
||||
@@ -4910,8 +4894,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"title": [Function],
|
||||
"visible": [Function],
|
||||
},
|
||||
"renewToken": [Function],
|
||||
"renewTokenError": [Function],
|
||||
"resourceTokenCollection": [Function],
|
||||
"resourceTokenCollectionId": [Function],
|
||||
"resourceTokenDatabaseId": [Function],
|
||||
@@ -5004,7 +4986,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"shouldShowContextSwitchPrompt": [Function],
|
||||
"shouldShowDataAccessExpiryDialog": [Function],
|
||||
"shouldShowShareDialogContents": [Function],
|
||||
"signInAad": [Function],
|
||||
"sparkClusterConnectionInfo": [Function],
|
||||
"splashScreenAdapter": SplashScreenComponentAdapter {
|
||||
"clearMostRecent": [Function],
|
||||
@@ -5071,7 +5052,6 @@ exports[`SettingsComponent renders 1`] = `
|
||||
"toggleLeftPaneExpandedKeyPress": [Function],
|
||||
"toggleRead": [Function],
|
||||
"toggleReadWrite": [Function],
|
||||
"tokenForRenewal": [Function],
|
||||
"uploadFilePane": UploadFilePane {
|
||||
"container": [Circular],
|
||||
"extensions": [Function],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import { SmartUiComponent, Descriptor, InputType } from "./SmartUiComponent";
|
||||
import React from "react";
|
||||
import { Descriptor, SmartUiComponent } from "./SmartUiComponent";
|
||||
|
||||
describe("SmartUiComponent", () => {
|
||||
const exampleData: Descriptor = {
|
||||
@@ -77,9 +77,7 @@ describe("SmartUiComponent", () => {
|
||||
}
|
||||
};
|
||||
|
||||
const exampleCallbacks = (newValues: Map<string, InputType>): void => {
|
||||
console.log("New values:", newValues);
|
||||
};
|
||||
const exampleCallbacks = (): void => undefined;
|
||||
|
||||
it("should render", () => {
|
||||
const wrapper = shallow(<SmartUiComponent descriptor={exampleData} onChange={exampleCallbacks} />);
|
||||
|
||||
@@ -214,8 +214,6 @@ export default class Explorer {
|
||||
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>;
|
||||
@@ -314,7 +312,7 @@ export default class Explorer {
|
||||
this.isSynapseLinkUpdating = ko.observable<boolean>(false);
|
||||
this.isAccountReady.subscribe(async (isAccountReady: boolean) => {
|
||||
if (isAccountReady) {
|
||||
this.isAuthWithResourceToken() ? this.refreshDatabaseForResourceToken() : this.refreshAllDatabases(true);
|
||||
this.isAuthWithResourceToken() ? await this.refreshDatabaseForResourceToken() : this.refreshAllDatabases(true);
|
||||
RouteHandler.getInstance().initHandler();
|
||||
this.notebookWorkspaceManager = new NotebookWorkspaceManager();
|
||||
this.arcadiaWorkspaces = ko.observableArray();
|
||||
@@ -381,8 +379,6 @@ export default class Explorer {
|
||||
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");
|
||||
@@ -414,7 +410,6 @@ export default class Explorer {
|
||||
|
||||
this.isSchemaEnabled = ko.computed<boolean>(() => this.isFeatureEnabled(Constants.Features.enableSchema));
|
||||
this.isNotificationConsoleExpanded = ko.observable<boolean>(false);
|
||||
|
||||
this.isAutoscaleDefaultEnabled = ko.observable<boolean>(false);
|
||||
|
||||
this.databases = ko.observableArray<ViewModels.Database>();
|
||||
@@ -1095,25 +1090,6 @@ export default class Explorer {
|
||||
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(
|
||||
@@ -1265,16 +1241,6 @@ export default class Explorer {
|
||||
$("#contextSwitchPrompt").dialog("open");
|
||||
}
|
||||
|
||||
public displayConnectExplorerForm(): void {
|
||||
$("#divExplorer").hide();
|
||||
$("#connectExplorer").css("display", "flex");
|
||||
}
|
||||
|
||||
public hideConnectExplorerForm(): void {
|
||||
$("#connectExplorer").hide();
|
||||
$("#divExplorer").show();
|
||||
}
|
||||
|
||||
public isReadWriteToggled: () => boolean = (): boolean => {
|
||||
return this.shareAccessToggleState() === ShareAccessToggleState.ReadWrite;
|
||||
};
|
||||
@@ -1364,21 +1330,17 @@ export default class Explorer {
|
||||
}
|
||||
}
|
||||
|
||||
public refreshDatabaseForResourceToken(): Q.Promise<any> {
|
||||
public async refreshDatabaseForResourceToken(): Promise<any> {
|
||||
const databaseId = this.resourceTokenDatabaseId();
|
||||
const collectionId = this.resourceTokenCollectionId();
|
||||
if (!databaseId || !collectionId) {
|
||||
return Q.reject();
|
||||
throw new Error("No collection ID or database ID for resource token");
|
||||
}
|
||||
|
||||
const deferred: Q.Deferred<void> = Q.defer();
|
||||
readCollection(databaseId, collectionId).then((collection: DataModels.Collection) => {
|
||||
return readCollection(databaseId, collectionId).then((collection: DataModels.Collection) => {
|
||||
this.resourceTokenCollection(new ResourceTokenCollection(this, databaseId, collection));
|
||||
this.selectedNode(this.resourceTokenCollection());
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
public refreshAllDatabases(isInitialLoad?: boolean): Q.Promise<any> {
|
||||
@@ -1848,7 +1810,7 @@ export default class Explorer {
|
||||
if (inputs != null) {
|
||||
// In development mode, save the iframe message from the portal in session storage.
|
||||
// This allows webpack hot reload to funciton properly
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
if (process.env.NODE_ENV === "development" && configContext.platform === Platform.Portal) {
|
||||
sessionStorage.setItem("portalDataExplorerInitMessage", JSON.stringify(inputs));
|
||||
}
|
||||
|
||||
@@ -1883,16 +1845,6 @@ export default class Explorer {
|
||||
subscriptionType: inputs.subscriptionType,
|
||||
quotaId: inputs.quotaId
|
||||
});
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.LoadDatabaseAccount,
|
||||
{
|
||||
resourceId: this.databaseAccount && this.databaseAccount().id,
|
||||
dataExplorerArea: Constants.Areas.ResourceTree,
|
||||
databaseAccount: this.databaseAccount && this.databaseAccount()
|
||||
},
|
||||
inputs.loadDatabaseAccountTimestamp
|
||||
);
|
||||
|
||||
this.isAccountReady(true);
|
||||
}
|
||||
}
|
||||
@@ -1974,18 +1926,6 @@ export default class Explorer {
|
||||
this.commandBarComponentAdapter.onUpdateTabsButtons(buttons);
|
||||
}
|
||||
|
||||
public signInAad = () => {
|
||||
TelemetryProcessor.trace(Action.SignInAad, undefined, { area: "Explorer" });
|
||||
sendMessage({
|
||||
type: MessageTypes.AadSignIn
|
||||
});
|
||||
};
|
||||
|
||||
public onSwitchToConnectionString = () => {
|
||||
$("#connectWithAad").hide();
|
||||
$("#connectWithConnectionString").show();
|
||||
};
|
||||
|
||||
public clickHostedAccountSwitch = () => {
|
||||
sendMessage({
|
||||
type: MessageTypes.UpdateAccountSwitch,
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
import React from "react";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import { MeControlComponent, MeControlComponentProps } from "./MeControlComponent";
|
||||
|
||||
const createNotSignedInProps = (): MeControlComponentProps => {
|
||||
return {
|
||||
isUserSignedIn: false,
|
||||
user: null,
|
||||
onSignInClick: jest.fn(),
|
||||
onSignOutClick: jest.fn(),
|
||||
onSwitchDirectoryClick: jest.fn()
|
||||
};
|
||||
};
|
||||
|
||||
const createSignedInProps = (): MeControlComponentProps => {
|
||||
return {
|
||||
isUserSignedIn: true,
|
||||
user: {
|
||||
name: "Test User",
|
||||
email: "testuser@contoso.com",
|
||||
tenantName: "Contoso",
|
||||
imageUrl: "../../../../images/dotnet.png"
|
||||
},
|
||||
onSignInClick: jest.fn(),
|
||||
onSignOutClick: jest.fn(),
|
||||
onSwitchDirectoryClick: jest.fn()
|
||||
};
|
||||
};
|
||||
|
||||
describe("test render", () => {
|
||||
it("renders not signed in", () => {
|
||||
const props = createNotSignedInProps();
|
||||
|
||||
const wrapper = shallow(<MeControlComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("renders signed in with full info", () => {
|
||||
const props = createSignedInProps();
|
||||
|
||||
const wrapper = shallow(<MeControlComponent {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("change not signed in to signed in", () => {
|
||||
const notSignInProps = createNotSignedInProps();
|
||||
|
||||
const wrapper = mount(<MeControlComponent {...notSignInProps} />);
|
||||
expect(wrapper.exists(".mecontrolSigninButton")).toBe(true);
|
||||
expect(wrapper.exists(".mecontrolHeaderButton")).toBe(false);
|
||||
|
||||
const signInProps = createSignedInProps();
|
||||
|
||||
wrapper.setProps(signInProps);
|
||||
expect(wrapper.exists(".mecontrolSigninButton")).toBe(false);
|
||||
expect(wrapper.exists(".mecontrolHeaderButton")).toBe(true);
|
||||
|
||||
wrapper.unmount;
|
||||
});
|
||||
|
||||
it("render contextual menu", () => {
|
||||
const signInProps = createSignedInProps();
|
||||
const wrapper = mount(<MeControlComponent {...signInProps} />);
|
||||
|
||||
wrapper.find("button.mecontrolHeaderButton").simulate("click");
|
||||
expect(wrapper.exists(".mecontrolContextualMenu")).toBe(true);
|
||||
|
||||
wrapper.find("button.mecontrolHeaderButton").simulate("click");
|
||||
expect(wrapper.exists(".mecontrolContextualMenu")).toBe(false);
|
||||
|
||||
wrapper.unmount;
|
||||
});
|
||||
});
|
||||
|
||||
describe("test function got called", () => {
|
||||
it("sign in click", () => {
|
||||
const notSignInProps = createNotSignedInProps();
|
||||
const wrapper = mount(<MeControlComponent {...notSignInProps} />);
|
||||
|
||||
wrapper.find("button.mecontrolSigninButton").simulate("click");
|
||||
expect(notSignInProps.onSignInClick).toBeCalled();
|
||||
expect(notSignInProps.onSignInClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("sign out click", () => {
|
||||
const signInProps = createSignedInProps();
|
||||
const wrapper = mount(<MeControlComponent {...signInProps} />);
|
||||
|
||||
wrapper.find("button.mecontrolHeaderButton").simulate("click");
|
||||
expect(wrapper.exists(".mecontrolContextualMenu")).toBe(true);
|
||||
|
||||
wrapper.find("div.signOutLink").simulate("click");
|
||||
expect(signInProps.onSignOutClick).toBeCalled();
|
||||
expect(signInProps.onSignOutClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("switch directory", () => {
|
||||
const signInProps = createSignedInProps();
|
||||
const wrapper = mount(<MeControlComponent {...signInProps} />);
|
||||
|
||||
wrapper.find("button.mecontrolHeaderButton").simulate("click");
|
||||
expect(wrapper.exists(".mecontrolContextualMenu")).toBe(true);
|
||||
|
||||
wrapper.find("div.switchDirectoryLink").simulate("click");
|
||||
expect(signInProps.onSwitchDirectoryClick).toBeCalled();
|
||||
expect(signInProps.onSwitchDirectoryClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,167 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { DefaultButton, BaseButton, IButtonProps } from "office-ui-fabric-react/lib/Button";
|
||||
import { DirectionalHint, IContextualMenuProps } from "office-ui-fabric-react/lib/ContextualMenu";
|
||||
import { FocusZone } from "office-ui-fabric-react/lib/FocusZone";
|
||||
import { IPersonaSharedProps, Persona, PersonaInitialsColor, PersonaSize } from "office-ui-fabric-react/lib/Persona";
|
||||
|
||||
export interface MeControlComponentProps {
|
||||
/**
|
||||
* Wheather user is signed in or not
|
||||
*/
|
||||
isUserSignedIn: boolean;
|
||||
/**
|
||||
* User info
|
||||
*/
|
||||
user: MeControlUser;
|
||||
/**
|
||||
* Click handler for sign in click
|
||||
*/
|
||||
onSignInClick: (e: React.MouseEvent<BaseButton>) => void;
|
||||
/**
|
||||
* Click handler for sign out click
|
||||
*/
|
||||
onSignOutClick: (e: React.SyntheticEvent) => void;
|
||||
/**
|
||||
* Click handler for switch directory click
|
||||
*/
|
||||
onSwitchDirectoryClick: (e: React.SyntheticEvent) => void;
|
||||
}
|
||||
|
||||
export interface MeControlUser {
|
||||
/**
|
||||
* Display name for user
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Display email for user
|
||||
*/
|
||||
email: string;
|
||||
/**
|
||||
* Display tenant for user
|
||||
*/
|
||||
tenantName: string;
|
||||
/**
|
||||
* image source for the profic photo
|
||||
*/
|
||||
imageUrl: string;
|
||||
}
|
||||
|
||||
export class MeControlComponent extends React.Component<MeControlComponentProps> {
|
||||
public render(): JSX.Element {
|
||||
return this.props.isUserSignedIn ? this._renderProfileComponent() : this._renderSignInComponent();
|
||||
}
|
||||
|
||||
private _renderProfileComponent(): JSX.Element {
|
||||
const { user } = this.props;
|
||||
|
||||
const menuProps: IContextualMenuProps = {
|
||||
className: "mecontrolContextualMenu",
|
||||
isBeakVisible: false,
|
||||
directionalHintFixed: true,
|
||||
directionalHint: DirectionalHint.bottomRightEdge,
|
||||
calloutProps: {
|
||||
minPagePadding: 0
|
||||
},
|
||||
items: [
|
||||
{
|
||||
key: "Persona",
|
||||
onRender: this._renderPersonaComponent
|
||||
},
|
||||
{
|
||||
key: "SwitchDirectory",
|
||||
onRender: this._renderSwitchDirectory
|
||||
},
|
||||
{
|
||||
key: "SignOut",
|
||||
onRender: this._renderSignOut
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const personaProps: IPersonaSharedProps = {
|
||||
imageUrl: user.imageUrl,
|
||||
text: user.email,
|
||||
secondaryText: user.tenantName,
|
||||
showSecondaryText: true,
|
||||
showInitialsUntilImageLoads: true,
|
||||
initialsColor: PersonaInitialsColor.teal,
|
||||
size: PersonaSize.size28,
|
||||
className: "mecontrolHeaderPersona"
|
||||
};
|
||||
|
||||
const buttonProps: IButtonProps = {
|
||||
id: "mecontrolHeader",
|
||||
className: "mecontrolHeaderButton",
|
||||
menuProps: menuProps,
|
||||
onRenderMenuIcon: () => <span />,
|
||||
styles: {
|
||||
rootHovered: { backgroundColor: "#393939" },
|
||||
rootFocused: { backgroundColor: "#393939" },
|
||||
rootPressed: { backgroundColor: "#393939" },
|
||||
rootExpanded: { backgroundColor: "#393939" }
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FocusZone>
|
||||
<DefaultButton {...buttonProps}>
|
||||
<Persona {...personaProps} />
|
||||
</DefaultButton>
|
||||
</FocusZone>
|
||||
);
|
||||
}
|
||||
|
||||
private _renderPersonaComponent = (): JSX.Element => {
|
||||
const { user } = this.props;
|
||||
const personaProps: IPersonaSharedProps = {
|
||||
imageUrl: user.imageUrl,
|
||||
text: user.name,
|
||||
secondaryText: user.email,
|
||||
showSecondaryText: true,
|
||||
showInitialsUntilImageLoads: true,
|
||||
initialsColor: PersonaInitialsColor.teal,
|
||||
size: PersonaSize.size72,
|
||||
className: "mecontrolContextualMenuPersona"
|
||||
};
|
||||
|
||||
return <Persona {...personaProps} />;
|
||||
};
|
||||
|
||||
private _renderSwitchDirectory = (): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className="switchDirectoryLink"
|
||||
onClick={(e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) =>
|
||||
this.props.onSwitchDirectoryClick(e)
|
||||
}
|
||||
>
|
||||
Switch Directory
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
private _renderSignOut = (): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className="signOutLink"
|
||||
onClick={(e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => this.props.onSignOutClick(e)}
|
||||
>
|
||||
Sign out
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
private _renderSignInComponent = (): JSX.Element => {
|
||||
const buttonProps: IButtonProps = {
|
||||
className: "mecontrolSigninButton",
|
||||
text: "Sign In",
|
||||
onClick: (e: React.MouseEvent<BaseButton>) => this.props.onSignInClick(e),
|
||||
styles: {
|
||||
rootHovered: { backgroundColor: "#393939", color: "#fff" },
|
||||
rootFocused: { backgroundColor: "#393939", color: "#fff" },
|
||||
rootPressed: { backgroundColor: "#393939", color: "#fff" }
|
||||
}
|
||||
};
|
||||
return <DefaultButton {...buttonProps} />;
|
||||
};
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* This adapter is responsible to render the React component
|
||||
* If the component signals a change through the callback passed in the properties, it must render the React component when appropriate
|
||||
* and update any knockout observables passed from the parent.
|
||||
*/
|
||||
import * as React from "react";
|
||||
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||
import { MeControlComponent, MeControlComponentProps } from "./MeControlComponent";
|
||||
|
||||
export class MeControlComponentAdapter implements ReactAdapter {
|
||||
public parameters: ko.Observable<MeControlComponentProps>;
|
||||
|
||||
public renderComponent(): JSX.Element {
|
||||
return <MeControlComponent {...this.parameters()} />;
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`test render renders not signed in 1`] = `
|
||||
<CustomizedDefaultButton
|
||||
className="mecontrolSigninButton"
|
||||
onClick={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"rootFocused": Object {
|
||||
"backgroundColor": "#393939",
|
||||
"color": "#fff",
|
||||
},
|
||||
"rootHovered": Object {
|
||||
"backgroundColor": "#393939",
|
||||
"color": "#fff",
|
||||
},
|
||||
"rootPressed": Object {
|
||||
"backgroundColor": "#393939",
|
||||
"color": "#fff",
|
||||
},
|
||||
}
|
||||
}
|
||||
text="Sign In"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`test render renders signed in with full info 1`] = `
|
||||
<FocusZone
|
||||
direction={2}
|
||||
isCircularNavigation={false}
|
||||
shouldRaiseClicks={true}
|
||||
>
|
||||
<CustomizedDefaultButton
|
||||
className="mecontrolHeaderButton"
|
||||
id="mecontrolHeader"
|
||||
menuProps={
|
||||
Object {
|
||||
"calloutProps": Object {
|
||||
"minPagePadding": 0,
|
||||
},
|
||||
"className": "mecontrolContextualMenu",
|
||||
"directionalHint": 6,
|
||||
"directionalHintFixed": true,
|
||||
"isBeakVisible": false,
|
||||
"items": Array [
|
||||
Object {
|
||||
"key": "Persona",
|
||||
"onRender": [Function],
|
||||
},
|
||||
Object {
|
||||
"key": "SwitchDirectory",
|
||||
"onRender": [Function],
|
||||
},
|
||||
Object {
|
||||
"key": "SignOut",
|
||||
"onRender": [Function],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
onRenderMenuIcon={[Function]}
|
||||
styles={
|
||||
Object {
|
||||
"rootExpanded": Object {
|
||||
"backgroundColor": "#393939",
|
||||
},
|
||||
"rootFocused": Object {
|
||||
"backgroundColor": "#393939",
|
||||
},
|
||||
"rootHovered": Object {
|
||||
"backgroundColor": "#393939",
|
||||
},
|
||||
"rootPressed": Object {
|
||||
"backgroundColor": "#393939",
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
<StyledPersonaBase
|
||||
className="mecontrolHeaderPersona"
|
||||
imageUrl="../../../../images/dotnet.png"
|
||||
initialsColor={3}
|
||||
secondaryText="Contoso"
|
||||
showInitialsUntilImageLoads={true}
|
||||
showSecondaryText={true}
|
||||
size={7}
|
||||
text="testuser@contoso.com"
|
||||
/>
|
||||
</CustomizedDefaultButton>
|
||||
</FocusZone>
|
||||
`;
|
||||
@@ -2,7 +2,7 @@ import * as ko from "knockout";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { ConnectionStringParser } from "../../Platform/Hosted/Helpers/ConnectionStringParser";
|
||||
import { parseConnectionString } from "../../Platform/Hosted/Helpers/ConnectionStringParser";
|
||||
import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
|
||||
@@ -48,9 +48,7 @@ export class RenewAdHocAccessPane extends ContextualPaneBase {
|
||||
};
|
||||
|
||||
private _shouldShowContextSwitchPrompt(): boolean {
|
||||
const inputMetadata: DataModels.AccessInputMetadata = ConnectionStringParser.parseConnectionString(
|
||||
this.accessKey()
|
||||
);
|
||||
const inputMetadata: DataModels.AccessInputMetadata = parseConnectionString(this.accessKey());
|
||||
const apiKind: DataModels.ApiKind =
|
||||
this.container && DefaultExperienceUtility.getApiKindFromDefaultExperience(this.container.defaultExperience());
|
||||
const hasOpenedTabs: boolean =
|
||||
|
||||
Reference in New Issue
Block a user