Atualizar aplicativo para criar e listar Contêineres do SharePoint Embedded
- 13 minutos
Neste exercício, você atualizará o projeto existente para criar e recuperar Contêineres do SharePoint Embedded.
Adicionar funcionalidade de entrada ao front-end do React SPA
Vamos começar adicionando suporte para entrada do usuário no projeto front-end do React SPA. Isso envolve adicionar algum código de configuração para a Biblioteca de Autenticação da Microsoft (MSAL) e configurar o Microsoft Graph Toolkit com os detalhes de entrada necessários.
Configurar o provedor de autenticação
Localize e abra o arquivo ./src/index.tsx .
Adicione as seguintes importações após as importações existentes:
import { Providers } from "@microsoft/mgt-element";
import { Msal2Provider } from "@microsoft/mgt-msal2-provider";
import * as Constants from "./common/constants"
import * as Scopes from "./common/scopes";
Por fim, adicione o seguinte código antes do código de renderização do React para configurar um provedor MSAL global para o Microsoft Graph Toolkit:
Providers.globalProvider = new Msal2Provider({
clientId: Constants.CLIENT_ENTRA_APP_CLIENT_ID,
authority: Constants.CLIENT_ENTRA_APP_AUTHORITY,
scopes: [
...Scopes.GRAPH_OPENID_CONNECT_BASIC,
Scopes.GRAPH_USER_READ_ALL,
Scopes.GRAPH_FILES_READ_WRITE_ALL,
Scopes.GRAPH_SITES_READ_ALL,
Scopes.SPEMBEDDED_FILESTORAGECONTAINER_SELECTED
]
});
Atualize a página inicial do aplicativo para lidar com o processo de entrada e saída
Localize e abra o arquivo ./src/App.tsx . Remova a importação do logo.svg arquivo e, em seguida, adicione e atualize as importações restantes para refletir o seguinte código:
import React, {
useState, useEffect
} from "react";
import {
Providers,
ProviderState
} from "@microsoft/mgt-element";
import { Login } from "@microsoft/mgt-react";
import {
FluentProvider,
Text,
webLightTheme
} from "@fluentui/react-components"
import './App.css';
import {
InteractionRequiredAuthError,
PublicClientApplication
} from "@azure/msal-browser";
import * as Scopes from "./common/scopes";
import * as Constants from "./common/constants";
Após as instruções de importação, adicione o seguinte gancho personalizado do React para obter o status de entrada do usuário atual:
function useIsSignedIn() {
const [isSignedIn, setIsSignedIn] = useState(false);
useEffect(() => {
const updateState = async () => {
const provider = Providers.globalProvider;
setIsSignedIn(provider && provider.state === ProviderState.SignedIn);
};
Providers.onProviderUpdated(updateState);
updateState();
return () => {
Providers.removeProviderUpdatedListener(updateState);
}
}, []);
return isSignedIn;
}
Agora, atualize o App adicionando o seguinte código após a declaração:
const isSignedIn = useIsSignedIn();
const promptForContainerConsent = async (event: CustomEvent<undefined>): Promise<void> => {
const containerScopes = {
scopes: [Scopes.SPEMBEDDED_FILESTORAGECONTAINER_SELECTED],
redirectUri: `${window.location.protocol}://${window.location.hostname}${(window.location.port === '80' || window.location.port === '443') ? '' : ':' + window.location.port}`
};
const msalInstance = new PublicClientApplication({
auth: {
clientId: Constants.CLIENT_ENTRA_APP_CLIENT_ID,
authority: Constants.CLIENT_ENTRA_APP_AUTHORITY,
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: false,
},
});
msalInstance.acquireTokenSilent(containerScopes)
.then(response => {
console.log('tokenResponse', JSON.stringify(response));
})
.catch(async (error) => {
if (error instanceof InteractionRequiredAuthError) {
return msalInstance.acquireTokenPopup(containerScopes);
}
});
}
Esse código obterá primeiro o status de entrada atual do usuário e, em seguida, configurará e obterá um token de acesso depois que o usuário selecionar um botão na renderização.
Por fim, atualize a renderização do componente substituindo a instrução do return() componente pelo seguinte:
return (
<FluentProvider theme={webLightTheme}>
<div className="App">
<Text size={900} weight='bold'>Sample SPA SharePoint Embedded App</Text>
<Login loginCompleted={promptForContainerConsent} />
<div>
</div>
</div>
</FluentProvider>
);
Testar a autenticação para o aplicativo React
Agora vamos testar o aplicativo React do lado do cliente para garantir que a autenticação esteja funcionando.
Na linha de comando na pasta raiz do projeto, execute o seguinte comando:
npm run start
O script criará os projetos do lado do servidor & do lado do cliente, iniciá-los e iniciar um navegador para o projeto do lado do cliente:
Selecione o botão Entrar e entre usando a conta corporativa ou de estudante com acesso de administrador ao locatário do Microsoft 365.
Depois de entrar com sucesso, você será redirecionado de volta ao aplicativo React exibindo o nome e o email do usuário conectado:
Pare o servidor pressionando CTRL + C no console.
Adicionar a capacidade de listar e selecionar Contêineres
Com a configuração básica do projeto e configurada para dar suporte à autenticação do usuário, agora vamos adicionar suporte para listar e selecionar Contêineres na partição do locatário.
O gerenciamento de contêineres é uma operação privilegiada que requer um token de acesso que deve ser obtido no lado do servidor. Vamos começar criando primeiro as partes da API do lado do servidor para dar suporte ao aplicativo React.
Adicionar método utilitário para recuperar um token OBO para chamar o Microsoft Graph
Primeiro, precisamos de um arquivo de utilitário para obter um token usando o fluxo OAuth2 On-Behalf-Of usando nossa credencial existente.
Crie um novo arquivo ./server/auth.ts e adicione o seguinte código a ele:
import { ConfidentialClientApplication } from "@azure/msal-node";
require('isomorphic-fetch');
import * as MSGraph from '@microsoft/microsoft-graph-client';
import * as Scopes from './common/scopes';
export const getGraphToken = async (confidentialClient: ConfidentialClientApplication, token: string): Promise<[boolean, string | any]> => {
try {
const graphTokenRequest = {
oboAssertion: token,
scopes: [
Scopes.GRAPH_SITES_READ_ALL,
Scopes.SPEMBEDDED_FILESTORAGECONTAINER_SELECTED
]
};
const oboGraphToken = (await confidentialClient.acquireTokenOnBehalfOf(graphTokenRequest))!.accessToken;
return [true, oboGraphToken];
} catch (error: any) {
const errorResult = {
status: 500,
body: JSON.stringify({
message: `Unable to generate Microsoft Graph OBO token: ${error.message}`,
providedToken: token
})
};
return [false, errorResult];
}
}
Isso usará um ConfidentialClientApplication configurado e o token de ID do usuário e usará a biblioteca MSAL para solicitar um novo token que podemos usar para chamar o Microsoft Graph.
Adicionar o Gerenciamento de contêiner ao projeto de API do lado do servidor
Agora, vamos criar o manipulador para obter uma lista dos contêineres usando o Microsoft Graph a serem retornados ao nosso aplicativo React. Crie um novo arquivo ./server/listContainers.ts e adicione as seguintes importações a ele:
import {
Request,
Response
} from "restify";
import * as MSAL from "@azure/msal-node";
require('isomorphic-fetch');
import * as MSGraph from '@microsoft/microsoft-graph-client';
import { getGraphToken } from "./auth";
Em seguida, adicione o seguinte código para criar uma instância de um MSAL ConfidentialClientApplication que será usado para obter o token de acesso OBO:
const msalConfig: MSAL.Configuration = {
auth: {
clientId: process.env['API_ENTRA_APP_CLIENT_ID']!,
authority: process.env['API_ENTRA_APP_AUTHORITY']!,
clientSecret: process.env['API_ENTRA_APP_CLIENT_SECRET']!
},
system: {
loggerOptions: {
loggerCallback(loglevel: any, message: any, containsPii: any) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: MSAL.LogLevel.Verbose,
}
}
};
const confidentialClient = new MSAL.ConfidentialClientApplication(msalConfig);
Crie e exporte uma nova função que fará o seguinte:
- Verifique se a solicitação inclui um
Authorizationcabeçalho com um token de acesso. - Use esse token e para obter um token OBO que podemos usar para chamar o
ConfidentialClientApplicationMicrosoft Graph. - Use o token OBO para criar um novo
AuthenticationProvidercliente que usaremos para ligar para o Microsoft Graph.
export const listContainers = async (req: Request, res: Response) => {
if (!req.headers.authorization) {
res.send(401, { message: 'No access token provided.' });
return;
}
const [bearer, token] = (req.headers.authorization || '').split(' ');
const [graphSuccess, oboGraphToken] = await getGraphToken(confidentialClient, token);
if (!graphSuccess) {
res.send(200, oboGraphToken);
return;
}
const authProvider = (callback: MSGraph.AuthProviderCallback) => {
callback(null, oboGraphToken);
};
}
A última etapa é criar o cliente do Microsoft Graph e solicitar todos os contêineres que tenham um conjunto específico ContainerTypeId . Adicione o seguinte código imediatamente antes do colchete de fechamento da função:
try {
const graphClient = MSGraph.Client.init({
authProvider: authProvider,
defaultVersion: 'beta'
});
const graphResponse = await graphClient.api(`storage/fileStorage/containers?$filter=containerTypeId eq ${process.env["CONTAINER_TYPE_ID"]}`).get();
res.send(200, graphResponse);
return;
} catch (error: any) {
res.send(500, { message: `Unable to list containers: ${error.message}` });
return;
}
Adicione este novo endpoint ao nosso servidor restify. Localize e abra o arquivo ./server/index.ts , adicione uma única instrução de importação ao final das importações existentes e adicione um ouvinte para solicitações HTTP GET ao /api/listContainers ponto de extremidade:
import { listContainers } from "./listContainers";
...
server.get('/api/listContainers', async (req, res, next) => {
try {
const response = await listContainers(req, res);
res.send(200, response)
} catch (error: any) {
res.send(500, { message: `Error in API server: ${error.message}` });
}
next();
});
Atualize o projeto do React para exibir nossos Contêineres
Com a configuração da API do lado do servidor, podemos atualizar nosso projeto React para fornecer aos usuários uma interface para selecionar um contêiner existente ou criar um novo contêiner.
Comece criando uma nova interface, ./src/common/IContainer.ts, com o seguinte conteúdo para representar o objeto que enviaremos e receberemos das chamadas do Microsoft Graph:
export interface IContainer {
id: string;
displayName: string;
containerTypeId: string;
createdDateTime: string;
}
Crie um novo serviço que será usado para chamar nosso ponto de extremidade de API ou fazer chamadas diretas do aplicativo React para o Microsoft Graph. Crie um novo arquivo ./src/services/spembedded.ts e adicione o seguinte código a ele:
import { Providers, ProviderState } from '@microsoft/mgt-element';
import * as Msal from '@azure/msal-browser';
import * as Constants from './../common/constants';
import * as Scopes from './../common/scopes';
import { IContainer } from './../common/IContainer';
export default class SpEmbedded {
}
Em seguida, adicione uma função de utilitário para obter um token de acesso que podemos usar para chamar o Microsoft Graph. Isso criará uma MSAL PublicClientApplication que usaremos para enviar para chamar nossa API do lado do servidor. Adicione a seguinte função à classe Embedded do SharePoint:
async getApiAccessToken() {
const msalConfig: Msal.Configuration = {
auth: {
clientId: Constants.CLIENT_ENTRA_APP_CLIENT_ID,
authority: Constants.CLIENT_ENTRA_APP_AUTHORITY,
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: false
}
};
const scopes: Msal.SilentRequest = {
scopes: [`api://${Constants.CLIENT_ENTRA_APP_CLIENT_ID}/${Scopes.SPEMBEDDED_CONTAINER_MANAGE}`],
prompt: 'select_account',
redirectUri: `${window.location.protocol}//${window.location.hostname}${(window.location.port === '80' || window.location.port === '443') ? '' : ':' + window.location.port}`
};
const publicClientApplication = new Msal.PublicClientApplication(msalConfig);
await publicClientApplication.initialize();
let tokenResponse;
try {
tokenResponse = await publicClientApplication.acquireTokenSilent(scopes);
return tokenResponse.accessToken;
} catch (error) {
if (error instanceof Msal.InteractionRequiredAuthError) {
tokenResponse = await publicClientApplication.acquireTokenPopup(scopes);
return tokenResponse.accessToken;
}
console.log(error)
return null;
}
};
Adicione o método a seguir listContainers() que chamará nossa API do lado do servidor para obter uma lista de todos os nossos contêineres. Isso obterá o token de acesso retornado pelo método de utilitário e o incluirá em chamadas para a API do lado do servidor. Lembre-se de que esse token de acesso é usado para criar uma MSAL ConfidentialClientApplication para obter um token OBO para chamar o Microsoft Graph. Esse token OBO tem mais permissões concedidas a ele que só podemos obter de uma chamada do lado do servidor:
async listContainers(): Promise<IContainer[] | undefined> {
const api_endpoint = `${Constants.API_SERVER_URL}/api/listContainers`;
if (Providers.globalProvider.state === ProviderState.SignedIn) {
const token = await this.getApiAccessToken();
const containerRequestHeaders = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
const containerRequestOptions = {
method: 'GET',
headers: containerRequestHeaders
};
const response = await fetch(api_endpoint, containerRequestOptions);
if (response.ok) {
const containerResponse = await response.json();
return (containerResponse.value)
? (containerResponse.value) as IContainer[]
: undefined;
} else {
console.error(`Unable to list Containers: ${JSON.stringify(response)}`);
return undefined;
}
}
};
Agora, crie um novo componente do React que lidará com todas as nossas tarefas e interface do usuário do contêiner. Crie um novo arquivo, ./src/components/containers.tsx, e adicione o seguinte código a ele:
import React, { useEffect, useState } from 'react';
import {
Button,
Dialog, DialogActions, DialogContent, DialogSurface, DialogBody, DialogTitle, DialogTrigger,
Dropdown, Option,
Input, InputProps, InputOnChangeData,
Label,
Spinner,
makeStyles, shorthands, useId
} from '@fluentui/react-components';
import type {
OptionOnSelectData,
SelectionEvents
} from '@fluentui/react-combobox'
import { IContainer } from "./../common/IContainer";
import SpEmbedded from '../services/spembedded';
const spe = new SpEmbedded();
const useStyles = makeStyles({
root: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
...shorthands.padding('25px'),
},
containerSelector: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
rowGap: '10px',
...shorthands.padding('25px'),
},
containerSelectorControls: {
width: '400px',
},
dialogContent: {
display: 'flex',
flexDirection: 'column',
rowGap: '10px',
marginBottom: '25px'
}
});
export const Containers = (props: any) => {
// BOOKMARK 1 - constants & hooks
// BOOKMARK 2 - handlers go here
// BOOKMARK 3 - component rendering
return (
);
}
export default Containers;
Observação
Observe os // BOOKMARK # comentários no componente. Isso garante que você esteja adicionando código nos locais corretos.
A primeira etapa é obter uma lista dos contêineres. Comece adicionando o seguinte código antes de // BOOKMARK 1. Isso definirá alguns valores de estado para manter os contêineres recuperados de nossa API do lado do servidor:
const [containers, setContainers] = useState<IContainer[]>([]);
const [selectedContainer, setSelectedContainer] = useState<IContainer | undefined>(undefined);
const containerSelector = useId('containerSelector');
Em seguida, adicione o seguinte gancho do React para // BOOKMARK 1 obter todos os Containers quando a página for carregada e defina o objeto de estado que os rastreará:
useEffect(() => {
(async () => {
const containers = await spe.listContainers();
if (containers) {
setContainers(containers);
}
})();
}, []);
Crie um manipulador de eventos após a implementação do gancho do React que você acabou de adicionar que será acionado quando um usuário selecionar um Container no controle suspenso que adicionaremos à nossa UX:
const onContainerDropdownChange = (event: SelectionEvents, data: OptionOnSelectData) => {
const selected = containers.find((container) => container.id === data.optionValue);
setSelectedContainer(selected);
};
Atualize a renderização adicionando o seguinte ao return() método após o // BOOKMARK 3 código. Isso criará um DropDown controle e um espaço reservado em que adicionaremos uma lista do conteúdo no contêiner selecionado:
<div className={styles.root}>
<div className={styles.containerSelector}>
<Dropdown
id={containerSelector}
placeholder="Select a Storage Container"
className={styles.containerSelectorControls}
onOptionSelect={onContainerDropdownChange}>
{containers.map((option) => (
<Option key={option.id} value={option.id}>{option.displayName}</Option>
))}
</Dropdown>
</div>
{selectedContainer && (`[[TOOD]] container "${selectedContainer.displayName}" contents go here`)}
</div>
Esse código usa um objeto de estilo que adicionamos ao componente quando o criamos inicialmente. Para usar os estilos, adicione o seguinte código imediatamente antes da instrução e // BOOKMARK 3 do return() comentário:
const styles = useStyles();
A última etapa é adicionar nosso novo Containerscomponente ao aplicativo. Localize e abra o ./src/App.tsx arquivo e adicione a seguinte importação após as importações existentes:
import Containers from "./components/containers";
Localize a <div></div> marcação no arquivo return(). Substitua essa marcação pelo seguinte para adicionar nosso Containers componente somente se o usuário estiver conectado:
<div>
{isSignedIn && (<Containers />)}
</div>
Testar a listagem e a seleção de contêineres
Agora vamos testar o aplicativo React do lado do cliente para ver os efeitos de nossas alterações para listar e exibir contêineres no aplicativo React.
Na linha de comando na pasta raiz do projeto, execute o seguinte comando:
npm run start
Quando o navegador for carregado, entre usando a mesma conta corporativa ou de estudante que você estava usando.
Após entrar, a página será recarregada e deverá exibir uma lista de Contêineres, se você já tiver criado algum.
Quando você seleciona um Container, observe que a lógica condicional mostrará o espaço reservado com o nome do Container selecionado:
Pare o servidor pressionando CTRL + C no console.
Adicionar a capacidade de criar novos contêineres
Nesta seção, você atualizará a API do lado do servidor e o aplicativo React para criar novos conteúdos a partir de nosso aplicativo Web.
Vamos começar criando primeiro as partes da API do lado do servidor para dar suporte ao aplicativo React.
Adicione suporte para criar contêineres ao projeto de API do lado do servidor
Agora vamos criar o manipulador para criar um contêiner usando o Microsoft Graph para ser retornado ao nosso aplicativo React. Crie um novo arquivo ./server/createContainer.ts e adicione as seguintes importações a ele:
import {
Request,
Response
} from "restify";
import * as MSAL from "@azure/msal-node";
require('isomorphic-fetch');
import * as MSGraph from '@microsoft/microsoft-graph-client';
import { getGraphToken } from "./auth";
Em seguida, adicione o seguinte código para criar uma instância de uma MSAL ConfidentialClientApplication que será usada para obter o token de acesso do OBO:
const msalConfig: MSAL.Configuration = {
auth: {
clientId: process.env['API_ENTRA_APP_CLIENT_ID']!,
authority: process.env['API_ENTRA_APP_AUTHORITY']!,
clientSecret: process.env['API_ENTRA_APP_CLIENT_SECRET']!
},
system: {
loggerOptions: {
loggerCallback(loglevel: any, message: any, containsPii: any) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: MSAL.LogLevel.Verbose,
}
}
};
const confidentialClient = new MSAL.ConfidentialClientApplication(msalConfig);
Crie e exporte uma nova função que fará o seguinte:
- Verifique se a solicitação inclui um
Authorizationcabeçalho com um token de acesso. - Use esse token e para obter um token OBO que podemos usar para chamar o
ConfidentialClientApplicationMicrosoft Graph. - Use o token OBO para criar um novo
AuthenticationProvidercliente que usaremos para ligar para o Microsoft Graph.
export const createContainer = async (req: Request, res: Response) => {
if (!req.headers.authorization) {
res.send(401, { message: 'No access token provided.' });
return;
}
const [bearer, token] = (req.headers.authorization || '').split(' ');
const [graphSuccess, graphTokenRequest] = await getGraphToken(confidentialClient, token);
if (!graphSuccess) {
res.send(200, graphTokenRequest);
return;
}
const authProvider = (callback: MSGraph.AuthProviderCallback) => {
callback(null, graphTokenRequest);
};
}
A última etapa é criar o cliente do Microsoft Graph e enviar a solicitação para criar um novo conjunto de contêineres para um arquivo .ContainerTypeId Adicione o seguinte código imediatamente antes do colchete de fechamento da função:
try {
const graphClient = MSGraph.Client.init({
authProvider: authProvider,
defaultVersion: 'beta'
});
const containerRequestData = {
displayName: req.body!.displayName,
description: (req.body?.description) ? req.body.description : '',
containerTypeId: process.env["CONTAINER_TYPE_ID"]
};
const graphResponse = await graphClient.api(`storage/fileStorage/containers`).post(containerRequestData);
res.send(200, graphResponse);
return;
} catch (error: any) {
res.send(500, { message: `Failed to create container: ${error.message}` });
return;
}
Adicione este novo endpoint ao nosso servidor restify. Localize e abra o arquivo ./server/index.ts , adicione uma única instrução de importação ao final das importações existentes e adicione um ouvinte para solicitações HTTP POST ao /api/createContainers ponto de extremidade:
import { createContainer } from "./createContainer";
...
server.post('/api/createContainer', async (req, res, next) => {
try {
const response = await createContainer(req, res);
res.send(200, response)
} catch (error: any) {
res.send(500, { message: `Error in API server: ${error.message}` });
}
next();
});
Atualize o projeto do React para criar um novo contêiner
Localize e abra o arquivo ./src/services/spembedded.ts e adicione o seguinte código à classe:
async createContainer(containerName: string, containerDescription: string = ''): Promise<IContainer | undefined> {
const api_endpoint = `${Constants.API_SERVER_URL}/api/createContainer`;
if (Providers.globalProvider.state === ProviderState.SignedIn) {
const token = await this.getApiAccessToken();
const containerRequestHeaders = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
const containerRequestData = {
displayName: containerName,
description: containerDescription
};
const containerRequestOptions = {
method: 'POST',
headers: containerRequestHeaders,
body: JSON.stringify(containerRequestData)
};
const response = await fetch(api_endpoint, containerRequestOptions);
if (response.ok) {
const containerResponse = await response.json();
return containerResponse as IContainer;
} else {
console.error(`Unable to create container: ${JSON.stringify(response)}`);
return undefined;
}
}
};
Esse novo método é semelhante ao método existente listContainers() , exceto que cria um novo objeto e o envia como um POST para nossa API do lado do servidor.
A última etapa é atualizar nosso Containers componente para atualizar a interface do usuário para oferecer suporte à criação de um contêiner. Localize e abra o arquivo ./src/components/containers.tsx .
Para esta etapa, usaremos um componente Fluent UI ReactDialog. Comece adicionando os seguintes objetos de estado e objetos de ID de componente de interface do usuário imediatamente antes do // BOOKMARK 1 comentário:
const [dialogOpen, setDialogOpen] = useState(false);
const containerName = useId('containerName');
const [name, setName] = useState('');
const containerDescription = useId('containerDescription');
const [description, setDescription] = useState('');
const [creatingContainer, setCreatingContainer] = useState(false);
Em seguida, adicione o código a seguir imediatamente antes do // BOOKMARK 2 comentário. Esses manipuladores são usados para atualizar as propriedades de nome e descrição do novo contêiner dos Input componentes que estarão no Dialogarquivo . Eles também são usados para lidar com o usuário seleciona um botão para criar o Contêiner:
const handleNameChange: InputProps["onChange"] = (event: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData): void => {
setName(data?.value);
};
const handleDescriptionChange: InputProps["onChange"] = (event: React.ChangeEvent<HTMLInputElement>, data: InputOnChangeData): void => {
setDescription(data?.value);
};
const onContainerCreateClick = async (event: React.MouseEvent<HTMLButtonElement>): Promise<void> => {
setCreatingContainer(true);
const newContainer = await spe.createContainer(name, description);
if (newContainer) {
setName('');
setDescription('');
setContainers(current => [...current, newContainer]);
setSelectedContainer(newContainer);
setDialogOpen(false);
} else {
setName('');
setDescription('');
}
setCreatingContainer(false);
}
Por fim, adicione o seguinte código React imediatamente após o elemento de fechamento</Dropdown>. Isso criará um componente Fluent UI React Dialog que é disparado a partir de um botão:
<Dialog open={dialogOpen} onOpenChange={(event, data) => setDialogOpen(data.open)}>
<DialogTrigger disableButtonEnhancement>
<Button className={styles.containerSelectorControls} appearance='primary'>Create a new storage Container</Button>
</DialogTrigger>
<DialogSurface>
<DialogBody>
<DialogTitle>Create a new storage Container</DialogTitle>
<DialogContent className={styles.dialogContent}>
<Label htmlFor={containerName}>Container name:</Label>
<Input id={containerName} className={styles.containerSelectorControls} autoFocus required
value={name} onChange={handleNameChange}></Input>
<Label htmlFor={containerDescription}>Container description:</Label>
<Input id={containerDescription} className={styles.containerSelectorControls} autoFocus required
value={description} onChange={handleDescriptionChange}></Input>
{creatingContainer &&
<Spinner size='medium' label='Creating storage Container...' labelPosition='after' />
}
</DialogContent>
<DialogActions>
<DialogTrigger disableButtonEnhancement>
<Button appearance="secondary" disabled={creatingContainer}>Cancel</Button>
</DialogTrigger>
<Button appearance="primary"
value={name}
onClick={onContainerCreateClick}
disabled={creatingContainer || (name === '')}>Create storage Container</Button>
</DialogActions>
</DialogBody>
</DialogSurface>
</Dialog>
Teste a criação de novos contêineres
Agora vamos testar o aplicativo React do lado do cliente para ver os efeitos de nossas alterações para criar contêineres no aplicativo React.
Na linha de comando na pasta raiz do projeto, execute o seguinte comando:
npm run start
Quando o navegador for carregado, entre usando a mesma conta corporativa ou de estudante que você estava usando.
Depois de entrar, a página será recarregada e agora deve incluir um botão para iniciar a caixa de diálogo:
Selecione o botão Criar um novo contêiner de armazenamento para abrir a caixa de diálogo. Observe como o botão fica desabilitado até que você digite um nome:
Insira um nome e uma descrição para o contêiner e selecione Criar contêiner de armazenamento. Ao criar o contêiner, os botões são desabilitados e um Spinner controle mostra ao usuário que está funcionando:
Assim que a caixa de diálogo desaparecer, você verá o seletor de novas exibições de nosso novo contêiner!
Pare o servidor pressionando CTRL + C no console.
Resumo
Neste exercício, você atualizou o projeto existente para criar e recuperar Contêineres do SharePoint Embedded.
Verifique seu conhecimento
Comentários
Esta página foi útil?
No
Precisa de ajuda com este tópico?
Quer experimentar o Pergunte e aprenda para esclarecer ou guiar você neste tópico?