when opening hosted explorer from portal, jump to selected sub/account
This commit is contained in:
parent
4866d3c902
commit
2bd913acbb
|
@ -6,13 +6,15 @@ import * as React from "react";
|
||||||
|
|
||||||
export const OpenFullScreen: React.FunctionComponent = () => {
|
export const OpenFullScreen: React.FunctionComponent = () => {
|
||||||
const searchParams = new URLSearchParams();
|
const searchParams = new URLSearchParams();
|
||||||
|
searchParams.append("openFrom", "portal");
|
||||||
|
|
||||||
let hasAccountContext = false;
|
let hasAccountContext = false;
|
||||||
let requiresConnectionString = false;
|
let requiresConnectionString = false;
|
||||||
|
|
||||||
if (userContext.authType === AuthType.AAD) {
|
if (userContext.authType === AuthType.AAD) {
|
||||||
if (userContext.subscriptionId && userContext.databaseAccount) {
|
if (userContext.subscriptionId && userContext.databaseAccount) {
|
||||||
searchParams.append("subscription", userContext.subscriptionId);
|
searchParams.append("subscription", userContext.subscriptionId);
|
||||||
searchParams.append("account", userContext.databaseAccount.id);
|
searchParams.append("account", userContext.databaseAccount.name);
|
||||||
searchParams.append("authType", "entra");
|
searchParams.append("authType", "entra");
|
||||||
hasAccountContext = true;
|
hasAccountContext = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { initializeIcons } from "@fluentui/react";
|
import { initializeIcons } from "@fluentui/react";
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import { AadAuthorizationFailure } from "Platform/Hosted/Components/AadAuthorizationFailure";
|
import { AadAuthorizationFailure } from "Platform/Hosted/Components/AadAuthorizationFailure";
|
||||||
import { getMsalInstance } from "Utils/AuthorizationUtils";
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { render } from "react-dom";
|
import { render } from "react-dom";
|
||||||
import ChevronRight from "../images/chevron-right.svg";
|
import ChevronRight from "../images/chevron-right.svg";
|
||||||
|
@ -34,7 +33,7 @@ const App: React.FunctionComponent = () => {
|
||||||
// For showing/hiding panel
|
// For showing/hiding panel
|
||||||
const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean(false);
|
const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean(false);
|
||||||
const config = useConfig();
|
const config = useConfig();
|
||||||
const { isLoggedIn, armToken, graphToken, account, tenantId, logout, login, switchTenant, authFailure } =
|
const { isLoggedIn, armToken, graphToken, account, tenantId, logout, forgetUser, login, switchTenant, authFailure } =
|
||||||
useAADAuth();
|
useAADAuth();
|
||||||
const [databaseAccount, setDatabaseAccount] = React.useState<DatabaseAccount>();
|
const [databaseAccount, setDatabaseAccount] = React.useState<DatabaseAccount>();
|
||||||
const [authType, setAuthType] = React.useState<AuthType>(encryptedToken ? AuthType.EncryptedToken : undefined);
|
const [authType, setAuthType] = React.useState<AuthType>(encryptedToken ? AuthType.EncryptedToken : undefined);
|
||||||
|
@ -43,23 +42,6 @@ const App: React.FunctionComponent = () => {
|
||||||
const ref = React.useRef<HTMLIFrameElement>();
|
const ref = React.useRef<HTMLIFrameElement>();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
(async () => {
|
|
||||||
const params = new URLSearchParams(window.location.search);
|
|
||||||
if (params.get("authType") === "entra") {
|
|
||||||
const msalInstance = await getMsalInstance();
|
|
||||||
const response = await msalInstance.handleRedirectPromise();
|
|
||||||
if (response) {
|
|
||||||
console.log("Redirect Promise Response", response);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Send the user to log in immediately
|
|
||||||
console.log("Starting non-interactive login");
|
|
||||||
login(false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// If ref.current is undefined no iframe has been rendered
|
// If ref.current is undefined no iframe has been rendered
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
// In hosted mode, we can set global properties directly on the child iframe.
|
// In hosted mode, we can set global properties directly on the child iframe.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { getMsalInstance } from "Utils/AuthorizationUtils";
|
import React, { useState } from "react";
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import Arrow from "../images/Arrow.svg";
|
import Arrow from "../images/Arrow.svg";
|
||||||
import CosmosDB_20170829 from "../images/CosmosDB_20170829.svg";
|
import CosmosDB_20170829 from "../images/CosmosDB_20170829.svg";
|
||||||
|
@ -14,14 +13,6 @@ const Index = (): JSX.Element => {
|
||||||
setNavigationSelection("quickstart");
|
setNavigationSelection("quickstart");
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
const msalInstance = await getMsalInstance();
|
|
||||||
console.log("handleRedirectPromise");
|
|
||||||
await msalInstance.handleRedirectPromise();
|
|
||||||
})();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const explorer_click = () => {
|
const explorer_click = () => {
|
||||||
setNavigationSelection("explorer");
|
setNavigationSelection("explorer");
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
/* eslint-disable react/display-name */
|
/* eslint-disable react/display-name */
|
||||||
|
|
||||||
import { DefaultButton, IButtonStyles, IContextualMenuItem } from "@fluentui/react";
|
import { DefaultButton, IButtonStyles, IContextualMenuItem } from "@fluentui/react";
|
||||||
|
import { urlContext } from "Utils/UrlContext";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FunctionComponent, useEffect, useState } from "react";
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
import { StyleConstants } from "../../../Common/StyleConstants";
|
import { StyleConstants } from "../../../Common/StyleConstants";
|
||||||
|
@ -50,12 +51,12 @@ interface Props {
|
||||||
export const AccountSwitcher: FunctionComponent<Props> = ({ armToken, setDatabaseAccount }: Props) => {
|
export const AccountSwitcher: FunctionComponent<Props> = ({ armToken, setDatabaseAccount }: Props) => {
|
||||||
const subscriptions = useSubscriptions(armToken);
|
const subscriptions = useSubscriptions(armToken);
|
||||||
const [selectedSubscriptionId, setSelectedSubscriptionId] = useState<string>(() =>
|
const [selectedSubscriptionId, setSelectedSubscriptionId] = useState<string>(() =>
|
||||||
localStorage.getItem("cachedSubscriptionId"),
|
urlContext.subscription || localStorage.getItem("cachedSubscriptionId"),
|
||||||
);
|
);
|
||||||
const selectedSubscription = subscriptions?.find((sub) => sub.subscriptionId === selectedSubscriptionId);
|
const selectedSubscription = subscriptions?.find((sub) => sub.subscriptionId === selectedSubscriptionId);
|
||||||
const accounts = useDatabaseAccounts(selectedSubscription?.subscriptionId, armToken);
|
const accounts = useDatabaseAccounts(selectedSubscription?.subscriptionId, armToken);
|
||||||
const [selectedAccountName, setSelectedAccountName] = useState<string>(() =>
|
const [selectedAccountName, setSelectedAccountName] = useState<string>(() =>
|
||||||
localStorage.getItem("cachedDatabaseAccountName"),
|
urlContext.account || localStorage.getItem("cachedDatabaseAccountName"),
|
||||||
);
|
);
|
||||||
const selectedAccount = accounts?.find((account) => account.name === selectedAccountName);
|
const selectedAccount = accounts?.find((account) => account.name === selectedAccountName);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { useNewPortalBackendEndpoint } from "Utils/EndpointUtils";
|
import { useNewPortalBackendEndpoint } from "Utils/EndpointUtils";
|
||||||
|
import { OpenedFrom, RequestedAuthType, urlContext } from "Utils/UrlContext";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import ConnectImage from "../../../../images/HdeConnectCosmosDB.svg";
|
import ConnectImage from "../../../../images/HdeConnectCosmosDB.svg";
|
||||||
import ErrorImage from "../../../../images/error.svg";
|
import ErrorImage from "../../../../images/error.svg";
|
||||||
|
@ -69,7 +70,9 @@ export const ConnectExplorer: React.FunctionComponent<Props> = ({
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [isFormVisible, { setTrue: showForm }] = useBoolean(false);
|
const [isFormVisible, { setTrue: showForm }] = useBoolean(false);
|
||||||
const [errorMessage, setErrorMessage] = React.useState("");
|
const [errorMessage, setErrorMessage] = React.useState("");
|
||||||
const enableConnectionStringLogin = !userContext.features.disableConnectionStringLogin;
|
const enableConnectionStringLogin =
|
||||||
|
urlContext.authType !== RequestedAuthType.Entra &&
|
||||||
|
!userContext.features.disableConnectionStringLogin;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="connectExplorer" className="connectExplorerContainer" style={{ display: "flex" }}>
|
<div id="connectExplorer" className="connectExplorerContainer" style={{ display: "flex" }}>
|
||||||
|
@ -137,6 +140,11 @@ export const ConnectExplorer: React.FunctionComponent<Props> = ({
|
||||||
Connect to your account with connection string
|
Connect to your account with connection string
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
{urlContext.openFrom === OpenedFrom.Portal && (
|
||||||
|
<p className="switchConnectTypeText">
|
||||||
|
Click sign in to continue your session from the Azure Portal.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
export enum OpenedFrom {
|
||||||
|
Portal = "portal",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum RequestedAuthType {
|
||||||
|
Entra = "entra",
|
||||||
|
ConnectionString = "connectionstring",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const urlContext = {
|
||||||
|
openFrom: urlParams.get("openFrom") as OpenedFrom,
|
||||||
|
authType: urlParams.get("authType") as RequestedAuthType,
|
||||||
|
subscription: urlParams.get("subscription"),
|
||||||
|
account: urlParams.get("account"),
|
||||||
|
};
|
|
@ -13,7 +13,7 @@ interface ReturnType {
|
||||||
isLoggedIn: boolean;
|
isLoggedIn: boolean;
|
||||||
graphToken: string;
|
graphToken: string;
|
||||||
armToken: string;
|
armToken: string;
|
||||||
login: (userTriggered?: boolean) => void;
|
login: () => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
tenantId: string;
|
tenantId: string;
|
||||||
account: msal.AccountInfo;
|
account: msal.AccountInfo;
|
||||||
|
@ -37,21 +37,9 @@ export function useAADAuth(): ReturnType {
|
||||||
const [armToken, setArmToken] = React.useState<string>();
|
const [armToken, setArmToken] = React.useState<string>();
|
||||||
const [authFailure, setAuthFailure] = React.useState<AadAuthFailure>(undefined);
|
const [authFailure, setAuthFailure] = React.useState<AadAuthFailure>(undefined);
|
||||||
|
|
||||||
console.log("Current AAD State", {
|
|
||||||
isLoggedIn, account, tenantId
|
|
||||||
});
|
|
||||||
|
|
||||||
msalInstance.setActiveAccount(account);
|
msalInstance.setActiveAccount(account);
|
||||||
const login = React.useCallback(async (userTriggered: boolean = true) => {
|
|
||||||
if (!userTriggered) {
|
const login = React.useCallback(async () => {
|
||||||
console.log("Starting non-interactive login");
|
|
||||||
// If the user didn't trigger the login, we don't want to pop up the login dialog
|
|
||||||
await msalInstance.acquireTokenRedirect({
|
|
||||||
redirectUri: configContext.msalRedirectURI,
|
|
||||||
scopes: [],
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const response = await msalInstance.loginPopup({
|
const response = await msalInstance.loginPopup({
|
||||||
redirectUri: configContext.msalRedirectURI,
|
redirectUri: configContext.msalRedirectURI,
|
||||||
scopes: [],
|
scopes: [],
|
||||||
|
|
Loading…
Reference in New Issue