Compare commits

..

1 Commits

Author SHA1 Message Date
Steve Faulkner
2a5ccbb51b Force enable notebooks 2021-04-08 21:55:48 -05:00
9 changed files with 70 additions and 171 deletions

View File

@@ -48,18 +48,32 @@ export function sendCachedDataMessage<TResponseDataModel>(
}
export function sendMessage(data: any): void {
_sendMessage({
signature: "pcIframe",
data: data,
});
if (canSendMessage()) {
// We try to find data explorer window first, then fallback to current window
const portalChildWindow = getDataExplorerWindow(window) || window;
portalChildWindow.parent.postMessage(
{
signature: "pcIframe",
data: data,
},
portalChildWindow.document.referrer || "*"
);
}
}
export function sendReadyMessage(): void {
_sendMessage({
signature: "pcIframe",
kind: "ready",
data: "ready",
});
if (canSendMessage()) {
// We try to find data explorer window first, then fallback to current window
const portalChildWindow = getDataExplorerWindow(window) || window;
portalChildWindow.parent.postMessage(
{
signature: "pcIframe",
kind: "ready",
data: "ready",
},
portalChildWindow.document.referrer || "*"
);
}
}
export function canSendMessage(): boolean {
@@ -75,17 +89,3 @@ export function runGarbageCollector() {
}
});
}
const _sendMessage = (message: any): void => {
if (canSendMessage()) {
// Portal window can receive messages from only child windows
const portalChildWindow = getDataExplorerWindow(window) || window;
if (portalChildWindow === window) {
// Current window is a child of portal, send message to portal window
portalChildWindow.parent.postMessage(message, portalChildWindow.document.referrer || "*");
} else {
// Current window is not a child of portal, send message to the child window instead (which is data explorer)
portalChildWindow.postMessage(message, portalChildWindow.location.origin || "*");
}
}
};

View File

@@ -300,11 +300,7 @@ export default class Explorer {
);
Promise.all([this._refreshNotebooksEnabledStateForAccount(), this._refreshSparkEnabledStateForAccount()]).then(
async () => {
this.isNotebookEnabled(
userContext.authType !== AuthType.ResourceToken &&
((await this._containsDefaultNotebookWorkspace(this.databaseAccount())) ||
userContext.features.enableNotebooks)
);
this.isNotebookEnabled(false);
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
isNotebookEnabled: this.isNotebookEnabled(),
@@ -1810,11 +1806,7 @@ export default class Explorer {
private async _refreshNotebooksEnabledStateForAccount(): Promise<void> {
const authType = userContext.authType;
if (
authType === AuthType.EncryptedToken ||
authType === AuthType.ResourceToken ||
authType === AuthType.MasterKey
) {
if (true) {
this.isNotebooksEnabledForAccount(false);
return;
}

View File

@@ -136,7 +136,7 @@ export function createFetchEdgePairQuery(
export function trimGraph(
currentRoot: GraphData.GremlinVertex,
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>
): void {
) {
const importantNodes = [currentRoot.id].concat(currentRoot._ancestorsId);
graphData.unloadAllVertices(importantNodes);
@@ -150,7 +150,7 @@ export function addRootChildToGraph(
root: GraphData.GremlinVertex,
child: GraphData.GremlinVertex,
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>
): void {
) {
child._ancestorsId = (root._ancestorsId || []).concat([root.id]);
graphData.addVertex(child);
createEdgesfromNode(child, graphData);

View File

@@ -456,7 +456,7 @@ function createEnableNotebooksButton(container: Explorer): CommandButtonComponen
onCommandClick: () => container.setupNotebooksPane.openWithTitleAndDescription(label, description),
commandButtonLabel: label,
hasPopup: false,
disabled: !container.isNotebooksEnabledForAccount(),
disabled: false,
ariaLabel: label,
tooltipText: container.isNotebooksEnabledForAccount() ? "" : tooltip,
};

View File

@@ -1,87 +0,0 @@
import { Callout, DefaultButton, DirectionalHint, Stack, TextField } from "office-ui-fabric-react";
import React from "react";
export interface DropdownItem {
key: string;
text: string;
}
export interface SearchableDropdownProps {
items: DropdownItem[];
onItemSelected: (selectedItem: DropdownItem) => void;
defaultSelectedItem?: DropdownItem;
placeholder?: string;
title?: string;
}
export interface SearchableDropdownState {
isDropdownExpanded: boolean;
selectedItem: DropdownItem;
filteredItems: DropdownItem[];
}
export class SearchableDropdown extends React.Component<SearchableDropdownProps, SearchableDropdownState> {
constructor(props: SearchableDropdownProps) {
super(props);
this.state = {
isDropdownExpanded: false,
selectedItem: props.defaultSelectedItem,
filteredItems: props.items,
};
}
public render(): JSX.Element {
return this.state.isDropdownExpanded ? (
<Stack>
<TextField
className="dropdownTextField"
title={this.props.title}
onChange={(event, newInput?: string) => this.onSearchInputChange(newInput)}
placeholder={this.props.placeholder}
autoFocus
/>
<Callout
isBeakVisible={false}
target=".dropdownTextField"
directionalHint={DirectionalHint.rightTopEdge}
onDismiss={() => this.setState({ isDropdownExpanded: false })}
gapSpace={0}
>
<Stack>
{this.state.filteredItems?.map((item) => (
<DefaultButton
key={item.key}
text={item.text}
style={{ border: "none", textAlign: "left" }}
styles={{ label: { fontWeight: "normal" } }}
onClick={() => this.onItemSelected(item)}
/>
))}
</Stack>
</Callout>
</Stack>
) : (
<TextField
className="dropdownTextField"
title={this.props.title}
onClick={() => this.setState({ isDropdownExpanded: true, filteredItems: this.props.items })}
value={this.state.selectedItem?.text || ""}
placeholder={this.props.placeholder}
readOnly
/>
);
}
private onSearchInputChange(newInput: string): void {
const filteredItems = this.props.items.filter((item: DropdownItem) =>
item.text.toLocaleLowerCase().includes(newInput.toLocaleLowerCase())
);
this.setState({ filteredItems });
}
private onItemSelected(item: DropdownItem): void {
this.setState({ selectedItem: item, isDropdownExpanded: false });
this.props.onItemSelected(item);
}
}

View File

@@ -1,6 +1,7 @@
import React from "react";
import { Dropdown } from "office-ui-fabric-react/lib/Dropdown";
import * as React from "react";
import { FunctionComponent } from "react";
import { DatabaseAccount } from "../../../Contracts/DataModels";
import { DropdownItem, SearchableDropdown } from "./SearchableDropdown";
interface Props {
accounts: DatabaseAccount[];
@@ -9,32 +10,30 @@ interface Props {
dismissMenu: () => void;
}
export const SwitchAccount: React.FunctionComponent<Props> = ({
export const SwitchAccount: FunctionComponent<Props> = ({
accounts,
setSelectedAccountName,
selectedAccount,
dismissMenu,
}: Props) => {
const accountItems = accounts?.map((account) => ({
key: account.name,
text: account.name,
}));
const defaultAccount = selectedAccount && {
key: selectedAccount.name,
text: selectedAccount.name,
};
return (
<SearchableDropdown
items={accountItems}
title="Cosmos DB Account Name"
defaultSelectedItem={defaultAccount}
placeholder={accounts?.length === 0 ? "No Accounts Found" : "Select an Account"}
onItemSelected={(accountItem: DropdownItem) => {
setSelectedAccountName(accountItem.key);
<Dropdown
label="Cosmos DB Account Name"
className="accountSwitchAccountDropdown"
options={accounts?.map((account) => ({
key: account.name,
text: account.name,
data: account,
}))}
onChange={(_, option) => {
setSelectedAccountName(String(option.key));
dismissMenu();
}}
defaultSelectedKey={selectedAccount?.name}
placeholder={accounts && accounts.length === 0 ? "No Accounts Found" : "Select an Account"}
styles={{
callout: "accountSwitchAccountDropdownMenu",
}}
/>
);
};

View File

@@ -1,6 +1,7 @@
import React from "react";
import { Dropdown } from "office-ui-fabric-react/lib/Dropdown";
import * as React from "react";
import { FunctionComponent } from "react";
import { Subscription } from "../../../Contracts/DataModels";
import { DropdownItem, SearchableDropdown } from "./SearchableDropdown";
interface Props {
subscriptions: Subscription[];
@@ -8,28 +9,30 @@ interface Props {
setSelectedSubscriptionId: (id: string) => void;
}
export const SwitchSubscription: React.FunctionComponent<Props> = ({
export const SwitchSubscription: FunctionComponent<Props> = ({
subscriptions,
setSelectedSubscriptionId,
selectedSubscription,
}: Props) => {
const subscriptionItems = subscriptions?.map((sub) => ({
key: sub.subscriptionId,
text: sub.displayName,
}));
const defaultSubscription = selectedSubscription && {
key: selectedSubscription.subscriptionId,
text: selectedSubscription.displayName,
};
return (
<SearchableDropdown
items={subscriptionItems}
title="Subscription"
defaultSelectedItem={defaultSubscription}
placeholder={subscriptions?.length === 0 ? "No Subscriptions Found" : "Select a Subscription"}
onItemSelected={(subscriptionItem: DropdownItem) => setSelectedSubscriptionId(subscriptionItem.key)}
<Dropdown
label="Subscription"
className="accountSwitchSubscriptionDropdown"
options={subscriptions?.map((sub) => {
return {
key: sub.subscriptionId,
text: sub.displayName,
data: sub,
};
})}
onChange={(_, option) => {
setSelectedSubscriptionId(String(option.key));
}}
defaultSelectedKey={selectedSubscription?.subscriptionId}
placeholder={subscriptions && subscriptions.length === 0 ? "No Subscriptions Found" : "Select a Subscription"}
styles={{
callout: "accountSwitchSubscriptionDropdownMenu",
}}
/>
);
};

View File

@@ -18,7 +18,6 @@ export function getAuthorizationHeader(): ViewModels.AuthorizationTokenHeaderMet
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function decryptJWTToken(token: string) {
if (!token) {
Logger.logError("Cannot decrypt token: No JWT token found", "AuthorizationUtils/decryptJWTToken");

View File

@@ -3,7 +3,7 @@ import { applyExplorerBindings } from "../applyExplorerBindings";
import { AuthType } from "../AuthType";
import { AccountKind, DefaultAccountExperience } from "../Common/Constants";
import { normalizeArmEndpoint } from "../Common/EnvironmentUtility";
import { sendMessage, sendReadyMessage } from "../Common/MessageHandler";
import { sendReadyMessage } from "../Common/MessageHandler";
import { configContext, Platform, updateConfigContext } from "../ConfigContext";
import { ActionType, DataExplorerAction } from "../Contracts/ActionContracts";
import { MessageTypes } from "../Contracts/ExplorerContracts";
@@ -266,8 +266,6 @@ async function configurePortal(explorerParams: ExplorerParams): Promise<Explorer
if (openAction) {
handleOpenAction(openAction, explorer.databases(), explorer);
}
} else if (shouldForwardMessage(message, event.origin)) {
sendMessage(message);
}
},
false
@@ -277,11 +275,6 @@ async function configurePortal(explorerParams: ExplorerParams): Promise<Explorer
});
}
function shouldForwardMessage(message: PortalMessage, messageOrigin: string) {
// Only allow forwarding messages from the same origin
return messageOrigin === window.document.location.origin && message.type === MessageTypes.TelemetryInfo;
}
function shouldProcessMessage(event: MessageEvent): boolean {
if (typeof event.data !== "object") {
return false;