diff --git a/item-counter-spe/src/index.tsx b/item-counter-spe/src/index.tsx index 972df1b20..c619a881a 100644 --- a/item-counter-spe/src/index.tsx +++ b/item-counter-spe/src/index.tsx @@ -1,17 +1,17 @@ -import React from "react"; +import type { AccountInfo, PublicClientApplication } from "@azure/msal-browser"; +import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces"; +import { OdspClient } from "@fluidframework/odsp-client/beta"; +import { AttachState } from "fluid-framework"; import { createRoot } from "react-dom/client"; -import { loadFluidData, containerSchema } from "./infra/fluid.js"; + +import { authHelper } from "./infra/authHelper.js"; import { getClientProps } from "./infra/clientProps.js"; -import { treeConfiguration } from "./schema.js"; +import { loadFluidData, containerSchema } from "./infra/fluid.js"; +import { GraphHelper } from "./infra/graphHelper.js"; +import { SampleOdspTokenProvider } from "./infra/tokenProvider.js"; import "./output.css"; import { ReactApp } from "./react_app.js"; -import { SampleOdspTokenProvider } from "./infra/tokenProvider.js"; -import { GraphHelper } from "./infra/graphHelper.js"; -import { authHelper } from "./infra/authHelper.js"; -import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces"; -import { OdspClient } from "@fluidframework/odsp-client/beta"; -import { AccountInfo, PublicClientApplication } from "@azure/msal-browser"; -import { AttachState } from "fluid-framework"; +import { treeConfiguration } from "./schema.js"; async function start() { const msalInstance = await authHelper(); @@ -21,15 +21,15 @@ async function start() { // If the tokenResponse is not null, then the user is signed in // and the tokenResponse is the result of the redirect. - if (tokenResponse !== null) { - await signedInStart(msalInstance, tokenResponse.account); - } else { + if (tokenResponse === null) { const currentAccounts = msalInstance.getAllAccounts(); if (currentAccounts.length === 0) { // no accounts signed-in, attempt to sign a user in - msalInstance.loginRedirect({ - scopes: ["FileStorageContainer.Selected", "Files.ReadWrite"], - }); + msalInstance + .loginRedirect({ + scopes: ["FileStorageContainer.Selected", "Files.ReadWrite"], + }) + .catch((error: unknown) => console.error(error)); } else if (currentAccounts.length > 1 || currentAccounts.length === 1) { // The user is singed in. // Treat more than one account signed in and a single account the same as @@ -38,6 +38,8 @@ async function start() { const account = msalInstance.getAllAccounts()[0]; await signedInStart(msalInstance, account); } + } else { + await signedInStart(msalInstance, tokenResponse.account); } } @@ -45,7 +47,7 @@ function showErrorMessage(message?: string, ...optionalParams: string[]) { // create the root element for React const error = document.createElement("div"); error.id = "app"; - document.body.appendChild(error); + document.body.append(error); const root = createRoot(error); // Render the error message @@ -72,7 +74,7 @@ async function signedInStart(msalInstance: PublicClientApplication, account: Acc // and the Fluid container id. If there is no hash, then the app will create a new Fluid container // in a later step. const getContainerInfo = async () => { - const shareId = location.hash.substring(1); + const shareId = location.hash.slice(1); if (shareId.length > 0) { try { return await graphHelper.getSharedItem(shareId); @@ -114,7 +116,7 @@ async function signedInStart(msalInstance: PublicClientApplication, account: Acc } // If the file storage container id is empty, then the app will fail here. - if (fileStorageContainerId.length == 0) { + if (fileStorageContainerId.length === 0) { return; } @@ -141,7 +143,7 @@ async function signedInStart(msalInstance: PublicClientApplication, account: Acc // Create the root element for React const app = document.createElement("div"); app.id = "app"; - document.body.appendChild(app); + document.body.append(app); const root = createRoot(app); // Initialize Fluid Container - this will either make a new container or load an existing one @@ -183,7 +185,7 @@ async function signedInStart(msalInstance: PublicClientApplication, account: Acc ); // Set the URL hash to the sharing id. - history.replaceState(undefined, "", "#" + shareId); + history.replaceState(undefined, "", `#${ shareId}`); } } diff --git a/item-counter-spe/src/infra/clientProps.ts b/item-counter-spe/src/infra/clientProps.ts index 111d37e6b..e2a2f4257 100644 --- a/item-counter-spe/src/infra/clientProps.ts +++ b/item-counter-spe/src/infra/clientProps.ts @@ -1,5 +1,5 @@ import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces"; -import { IOdspTokenProvider, OdspClientProps } from "@fluidframework/odsp-client/beta"; +import type { IOdspTokenProvider, OdspClientProps } from "@fluidframework/odsp-client/beta"; // Create the client props for the Fluid client export const getClientProps = ( @@ -9,9 +9,9 @@ export const getClientProps = ( logger?: ITelemetryBaseLogger, ): OdspClientProps => { const connectionConfig = { - tokenProvider: tokenProvider, - siteUrl: siteUrl, - driveId: driveId, + tokenProvider, + siteUrl, + driveId, filePath: "", }; diff --git a/item-counter-spe/src/infra/fluid.ts b/item-counter-spe/src/infra/fluid.ts index 40d4ff33f..3b84d750e 100644 --- a/item-counter-spe/src/infra/fluid.ts +++ b/item-counter-spe/src/infra/fluid.ts @@ -1,5 +1,5 @@ import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces"; -import { OdspClient, OdspContainerServices } from "@fluidframework/odsp-client/beta"; +import type { OdspClient, OdspContainerServices } from "@fluidframework/odsp-client/beta"; import { type ContainerSchema, type IFluidContainer, SharedTree } from "fluid-framework"; /** diff --git a/item-counter-spe/src/infra/graphHelper.ts b/item-counter-spe/src/infra/graphHelper.ts index ff9cf311e..2941b429f 100644 --- a/item-counter-spe/src/infra/graphHelper.ts +++ b/item-counter-spe/src/infra/graphHelper.ts @@ -1,10 +1,12 @@ -import { PublicClientApplication, InteractionType, AccountInfo } from "@azure/msal-browser"; +import type { PublicClientApplication, AccountInfo } from "@azure/msal-browser"; +import { InteractionType } from "@azure/msal-browser"; import { Client } from "@microsoft/microsoft-graph-client"; +import type { + AuthCodeMSALBrowserAuthenticationProviderOptions} from "@microsoft/microsoft-graph-client/authProviders/authCodeMsalBrowser/index.js"; import { - AuthCodeMSALBrowserAuthenticationProvider, - AuthCodeMSALBrowserAuthenticationProviderOptions, + AuthCodeMSALBrowserAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/authCodeMsalBrowser/index.js"; -import { Site } from "@microsoft/microsoft-graph-types"; +import type { Site } from "@microsoft/microsoft-graph-types"; export interface FileStorageContainer { containerTypeId: string; @@ -56,19 +58,19 @@ export class GraphHelper { try { const response = await this.graphClient .api("/storage/fileStorage/containers") - .filter("containerTypeId eq " + containerTypeId) + .filter(`containerTypeId eq ${ containerTypeId}`) .version("beta") .get(); const fileStorageContainers: FileStorageContainer[] = response.value; - if (fileStorageContainers.length == 0) { + if (fileStorageContainers.length === 0) { throw new Error("TEST: no fileStorageContainers"); } return fileStorageContainers[0].id; } catch (error) { - console.error("Error while fetching file storage container ID: ", error); + console.error("Error while fetching file storage container ID:", error); throw error; // re-throw the error if you want it to propagate } } @@ -97,7 +99,7 @@ export class GraphHelper { .api(`/drives/${driveId}/items/${id}/createLink`) .post(permission); - console.log("createSharingLink response: ", response.link); + console.log("createSharingLink response:", response.link); return response.shareId as string; } diff --git a/item-counter-spe/src/infra/tokenProvider.ts b/item-counter-spe/src/infra/tokenProvider.ts index 3a09fb4ba..ec92dc86e 100644 --- a/item-counter-spe/src/infra/tokenProvider.ts +++ b/item-counter-spe/src/infra/tokenProvider.ts @@ -1,9 +1,10 @@ -import { +import type { AuthenticationResult, - InteractionRequiredAuthError, - PublicClientApplication, + PublicClientApplication} from "@azure/msal-browser"; +import { + InteractionRequiredAuthError } from "@azure/msal-browser"; -import { IOdspTokenProvider, TokenResponse } from "@fluidframework/odsp-client/beta"; +import type { IOdspTokenProvider, TokenResponse } from "@fluidframework/odsp-client/beta"; // Sample implementation of the IOdspTokenProvider interface // This class is used to provide the token for the Fluid container and @@ -48,7 +49,7 @@ export class SampleOdspTokenProvider implements IOdspTokenProvider { scopes: scope, }); } else { - throw new Error(`MSAL error: ${error}`); + throw new TypeError(`MSAL error: ${error}`); } } return response.accessToken; diff --git a/item-counter-spe/src/react_app.tsx b/item-counter-spe/src/react_app.tsx index 27da13803..7390d596b 100644 --- a/item-counter-spe/src/react_app.tsx +++ b/item-counter-spe/src/react_app.tsx @@ -3,9 +3,12 @@ * Licensed under the MIT License. */ -import React, { JSX, ReactNode, useEffect, useState } from "react"; -import { TreeView, Tree } from "fluid-framework"; -import { StringArray } from "./schema.js"; +import type { TreeView} from "fluid-framework"; +import { Tree } from "fluid-framework"; +import type { JSX, ReactNode} from "react"; +import { useEffect, useState } from "react"; + +import type { StringArray } from "./schema.js"; export function ReactApp(props: { data: TreeView }): JSX.Element { return ( diff --git a/item-counter-spe/tsconfig.json b/item-counter-spe/tsconfig.json index 209d74ab1..b13074c5d 100644 --- a/item-counter-spe/tsconfig.json +++ b/item-counter-spe/tsconfig.json @@ -7,7 +7,7 @@ "sourceMap": true, // Set your preferences here for TypeScript "strict": true, - "jsx": "react", + "jsx": "react-jsx", "moduleResolution": "Node16", "allowSyntheticDefaultImports": true, "esModuleInterop": true,