Criar um aplicativo de guia dashboard

Um dashboard é uma ferramenta para rastrear, analisar e exibir dados para obter informações sobre uma organização ou um processo específico. Os painéis no Teams permitem monitorar e exibir métricas importantes.

O modelo de guia dashboard do Teams Toolkit permite que você comece a integrar uma tela com vários cartões que fornecem uma visão geral do conteúdo no Teams. Você pode:

  • Use widgets para exibir conteúdo de aplicativos e serviços na guia dashboard.
  • Integre seu aplicativo ao API do Graph para visualizar detalhes sobre a implementação dos dados selecionados.
  • Crie painéis personalizáveis que permitem que sua empresa defina metas específicas que ajudam você a rastrear as informações necessárias para exibir em várias áreas e em todos os departamentos.

A captura de tela mostra o exemplo de um dashboard.

Sua equipe pode obter as atualizações mais recentes de diferentes fontes no Teams usando o aplicativo de guia teams dashboard. Use dashboard aplicativos de guia para conectar várias métricas, fontes de dados, APIs e serviços. Os aplicativos de guia de painel ajudam sua empresa a extrair informações relevantes das fontes e apresentá-los aos usuários. Para obter mais informações sobre como criar um aplicativo de guia dashboard, consulte guia passo a passo.

Adicionar um novo dashboard

Depois de criar um aplicativo de guia dashboard, você pode adicionar um novo dashboard.

Para adicionar um novo dashboard, siga estas etapas:

  1. Criar uma classe dashboard
  2. Substituir métodos para personalizar dashboard aplicativo de guia
  3. Adicionar uma rota para o novo aplicativo de guia dashboard
  4. Modificar manifesto para adicionar um novo aplicativo de guia dashboard

Criar uma classe dashboard

Crie um arquivo com a .tsx extensão do dashboard no src/dashboards diretório, por exemplo, YourDashboard.tsx. Em seguida, crie uma classe que estende o BaseDashboard class from
@microsoft/teamsfx-react.

//YourDashboard.tsx
import { BaseDashboard } from "@microsoft/teamsfx-react";

export default class YourDashboard extends BaseDashboard<any, any> {}

Observação

Todos os métodos são opcionais. Se você não substituir nenhum método, o layout de dashboard padrão será usado.

Substituir métodos para personalizar dashboard aplicativo de guia

A BaseDashboard classe fornece poucos métodos que você pode substituir para personalizar o layout dashboard. A tabela a seguir lista os métodos que você pode substituir:

Métodos Function
styling() Personalize o estilo do dashboard.
layout() Definir layout de widgets.

O código a seguir é um exemplo para personalizar o layout do dashboard:

.your-dashboard-layout {
  grid-template-columns: 6fr 4fr;
}
import { BaseDashboard } from "@microsoft/teamsfx-react";
import ListWidget from "../widgets/ListWidget";
import ChartWidget from "../widgets/ChartWidget";

export default class YourDashboard extends BaseDashboard<any, any> {
  override styling(): string {
    return "your-dashboard-layout";
  }

  override layout(): JSX.Element | undefined {
    return (
      <>
        <ListWidget />
        <ChartWidget />
      </>
    );
  }
}

Adicionar uma rota para o novo aplicativo de guia dashboard

Você deve vincular seu widget a um arquivo de fonte de dados. O widget capta os dados apresentados no dashboard do arquivo de origem.

Abra o src/App.tsx arquivo e adicione uma rota para o novo dashboard. Veja um exemplo:

import YourDashboard from "./dashboards/YourDashboard";

export default function App() {
  ...
  <Route path="/yourdashboard" element={<YourDashboard />} />
  ...
}

Modificar manifesto para adicionar um novo aplicativo de guia dashboard

Abra o appPackage/manifest.json arquivo e adicione uma nova guia dashboard em staticTabs. Para obter mais informações, consulte o manifesto do aplicativo. Veja um exemplo:

{
  "entityId": "index1",
  "name": "Your Dashboard",
  "contentUrl": "${{TAB_ENDPOINT}}/index.html#/yourdashboard",
  "websiteUrl": "${{TAB_ENDPOINT}}/index.html#/yourdashboard",
  "scopes": ["personal"]
}

Personalizar o layout do dashboard

O TeamsFx fornece métodos convenientes para definir e modificar o layout do dashboard. A seguir estão os métodos:

  • Três widgets seguidos com a altura de 350 px ocupando 20%, 60% e 20% da largura, respectivamente.

    .customize-class-name {
      grid-template-rows: 350px;
      grid-template-columns: 2fr 6fr 2fr;
    }
    
    export default class SampleDashboard extends BaseDashboard<any, any> {
    
      override styling(): string {
        return "customize-class-name";
      }
    
      override layout(): JSX.Element | undefined {
        return (
          <>
           <ListWidget />
           <ChartWidget />
           <NewsWidget />
          </>
        );
      }
    }
    

    A captura de tela mostra o layout de dashboard personalizado.

  • Dois widgets em uma linha com uma largura de 600 px e 1100 px. A altura da primeira linha é a altura máxima de seu conteúdo e a altura da segunda linha é de 400 px.

    .customize-class-name {
      grid-template-rows: max-content 400px;
      grid-template-columns: 600px 1100px;
    }
    
        export default class SampleDashboard extends Dashboard {
      override styling(): string {
        return "customize-class-name";
      }
    
      override layout(): JSX.Element | undefined {
        return (
          <>
        <ListWidget />
        <ChartWidget />
        <NewsWidget />
          </>
        );
      }
        }
    

    A captura de tela mostra a personalização da altura e largura do layout do dashboard.

  • Organize dois widgets em uma coluna.

    .one-column {
        display: grid;
        gap: 20px;
        grid-template-rows: 1fr 1fr;
      }
    
      export default class SampleDashboard extends BaseDashboard<any, any> {
        override layout(): JSX.Element | undefined {
          return (
            <>
              <NewsWidget />
              <div className="one-column">
                <ListWidget />
                <ChartWidget />          
              </div>
            </>
          );
        }
      }
    

    A captura de tela mostra a personalização de dois widgets.

Abstração do aplicativo de guia de painel

Para ajustar o layout do dashboard, o TeamsFx fornece uma BaseDashboard classe para os desenvolvedores implementarem uma dashboard.

O código a seguir é um exemplo de uma BaseDashboard classe:

function dashboardStyle(isMobile?: boolean) {
  return mergeStyles({
    display: "grid",
    gap: "20px",
    padding: "20px",
    gridTemplateRows: "1fr",
    gridTemplateColumns: "4fr 6fr",
    ...(isMobile === true ? { gridTemplateColumns: "1fr", gridTemplateRows: "1fr" } : {}),
  });
}

interface BaseDashboardState {
  isMobile?: boolean;
  showLogin?: boolean;
  observer?: ResizeObserver;
}

export class BaseDashboard<P, S> extends Component<P, S & BaseDashboardState> {
  private ref: React.RefObject<HTMLDivElement>;

  public constructor(props: Readonly<P>) {
    super(props);
    this.state = {
      isMobile: undefined,
      showLogin: undefined,
      observer: undefined,
    } as S & BaseDashboardState;
    this.ref = React.createRef<HTMLDivElement>();
  }

  public async componentDidMount() {
    const observer = new ResizeObserver((entries) => {
      for (const entry of entries) {
        if (entry.target === this.ref.current) {
          const { width } = entry.contentRect;
          this.setState({ isMobile: width < 600 } as S & BaseDashboardState);
        }
      }
    });
    observer.observe(this.ref.current!);
  }

  public componentWillUnmount(): void {
    if (this.state.observer && this.ref.current) {
      this.state.observer.unobserve(this.ref.current);
    }
  }

  public render() {
    return (
      <div
        ref={this.ref}
        className={mergeStyles(dashboardStyle(this.state.isMobile), this.styling())}
      >
        {this.layout()}
      </div>
    );
  }

  protected layout(): JSX.Element | undefined {
    return undefined;
  }

  protected styling(): string {
    return null;
  }
}

Na classe, o BaseDashboard TeamsFx fornece layouts básicos com métodos personalizáveis. O dashboard ainda é um componente react e o TeamsFx fornece implementações básicas de funções com base no ciclo de vida dos componentes react, como:

  • Implementando uma lógica de renderização básica com base no layout da grade.
  • Adicionar um observador para se adaptar automaticamente a dispositivos móveis.

A seguir estão os métodos personalizáveis para substituir:

Métodos Função Recomendamos substituir
constructor() Inicializa o estado dashboard e as variáveis. Não
componentDidMount() Invoca depois que um componente é montado. Não
componentWillUnmount() Invoca quando um componente é desmontado. Não
render() Invoca quando há uma atualização. O layout padrão dashboard é definido neste método. Não
layout Define o layout do widget no dashboard. Você pode substituir esse método. Sim
styling() Para personalizar o estilo do dashboard. Você pode substituir esse método. Sim

Use um widget no dashboard

Os widgets exibem informações configuráveis e gráficos nos painéis. Eles aparecem no quadro de widget onde você pode fixar, desapinar, organizar, redimensionar e personalizar widgets para refletir seus interesses. Seu quadro de widget é otimizado para mostrar widgets relevantes e conteúdo personalizado com base no seu uso.

Personalizar o widget

Você pode personalizar o widget substituindo os seguintes métodos na BaseWidget classe:

  • Substitua header(), body()e footer() para personalizar o widget.

    export class NewsWidget extends BaseWidget<any, any> {
    override header(): JSX.Element | undefined {
    return (
      <div>
        <News28Regular />
        <Text>Your News</Text>
        <Button icon={<MoreHorizontal32Regular />} appearance="transparent" />
      </div>
    );
    }
    
    override body(): JSX.Element | undefined {
    return (
      <div>
        <Image src="image.svg" />
        <Text>Lorem Ipsum Dolor</Text>
        <Text>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Enim,
          elementum sed
        </Text>
      </div>
    );
    }
    
    override footer(): JSX.Element | undefined {
    return (
      <Button
        appearance="transparent"
        icon={<ArrowRight16Filled />}
        iconPosition="after"
        size="small"
      >
        View details
      </Button>
    );
    }
    }
    

    A captura de tela mostra o exemplo de conteúdo de cabeçalho, corpo e rodapé em um widget.

  • Substitua body() e footer() personalize o widget.

    export class NewsWidget extends BaseWidget<any, any> {
    override body(): JSX.Element | undefined {
    return (
      <div>
        <Image src="image.svg" />
        <Text>Lorem Ipsum Dolor</Text>
        <Text>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Enim,
          elementum sed
        </Text>
      </div>
    );
    }
    
    override footer(): JSX.Element | undefined {
    return (
      <Button
        appearance="transparent"
        icon={<ArrowRight16Filled />}
        iconPosition="after"
        size="small"
      >
        View details
      </Button>
    );
    }
    }
    

    A captura de tela mostra o conteúdo do corpo e do rodapé em um widget.

  • Substitua body() para personalizar o widget.

    export class NewsWidget extends BaseWidget<any, any> {
    override body(): JSX.Element | undefined {
    return (
      <div>
        <Image src="image.svg" />
        <Text>Lorem Ipsum Dolor</Text>
        <Text>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Enim,
          elementum sed
        </Text>
      </div>
    );
    }
    }
    

    A captura de tela mostra o conteúdo do corpo em um widget.

Incluir um carregador de dados

Se você quiser incluir um carregador de dados no widget antes que o widget seja carregado, você pode adicionar uma propriedade ao estado do widget para indicar que o carregador de dados é loading(). Você pode usar essa propriedade para mostrar um indicador de carregamento para o usuário.

Exemplo:

    override loading(): JSX.Element | undefined {
     return (
      <div className="loading">
       <Spinner label="Loading..." labelPosition="below" />
      </div>
     );
    }

Agora, o rotador de carregamento é mostrado enquanto os dados são carregados. Quando os dados são carregados, o rotador de carregamento fica oculto e os dados de lista e o botão rodapé são mostrados.

A representação gráfica mostra o rotador de carregamento enquanto os dados são carregados.

Manipular o estado vazio

Você pode exibir um conteúdo específico no widget quando os dados estiverem vazios. Para fazer isso, você precisa modificar o body método em seu arquivo widget para adotar diferentes estados dos dados.

O exemplo a seguir mostra como exibir uma imagem vazia quando os dados de ListWidget estão vazios.

override body(): JSX.Element | undefined {
  let hasData = this.state.data && this.state.data.length > 0;
  return (
    <div>
      {hasData ? (
        <>
          {this.state.data?.map((t: ListModel) => {
            ...
          })}
        </>
      ) : (
        <div>
          <Image src="empty-default.svg" height="150px" />
          <Text align="center">No data</Text>
        </div>
      )}
    </div>
  );
}

Você pode usar uma abordagem semelhante para remover o conteúdo do rodapé do widget quando os dados estiverem vazios.

  override footer(): JSX.Element | undefined {
    let hasData = this.state.data && this.state.data.length > 0;
    if (hasData) {
      return <Button>...</Button>;
    }
  }

Quando os dados estão vazios, o widget de lista aparece da seguinte maneira:

Captura de tela que não mostra nenhum dado na lista.

Atualizar dados conforme agendado

O exemplo a seguir mostra como exibir dados em tempo real em um widget. O widget exibe a hora e as atualizações atuais.

interface IRefreshWidgetState {
  data: string;
}

export class RefreshWidget extends BaseWidget<any, IRefreshWidgetState> {
  override body(): JSX.Element | undefined {
    return <>{this.state.data}</>;
  }

  async componentDidMount() {
    setInterval(() => {
      this.setState({ data: new Date().toLocaleTimeString() });
    }, 1000);
  }
}

Você pode modificar setInterval o método para chamar sua própria função para atualizar dados como este setInterval(() => yourGetDataFunction(), 1000).

Abstração do Widget

Para simplificar o desenvolvimento de um widget, o SDK do TeamsFx fornece uma BaseWidget classe para os desenvolvedores herdarem para implementar um widget que atenda às suas necessidades sem prestar muita atenção para implementar o layout do widget.

O código a seguir é um exemplo da classe BaseWidget:

export interface IWidgetClassNames {
  root?: string;
  header?: string;
  body?: string;
  footer?: string;
}

const classNames: IWidgetClassNames = mergeStyleSets({
  root: {
    display: "grid",
    padding: "1.25rem 2rem 1.25rem 2rem",
    backgroundColor: tokens.colorNeutralBackground1,
    border: "1px solid var(--colorTransparentStroke)",
    boxShadow: tokens.shadow4,
    borderRadius: tokens.borderRadiusMedium,
    gap: tokens.spacingHorizontalL,
    gridTemplateRows: "max-content 1fr max-content",
  },
  header: {
    display: "grid",
    height: "max-content",
    "& div": {
      display: "grid",
      gap: tokens.spacingHorizontalS,
      alignItems: "center",
      gridTemplateColumns: "min-content 1fr min-content",
    },
    "& svg": {
      height: "1.5rem",
      width: "1.5rem",
    },
    "& span": {
      fontWeight: tokens.fontWeightSemibold,
      lineHeight: tokens.lineHeightBase200,
      fontSize: tokens.fontSizeBase200,
    },
  },
  footer: {
    "& button": {
      width: "fit-content",
    },
  },
});

interface BaseWidgetState {
  loading?: boolean;
}

export class BaseWidget<P, S> extends Component<P, S & BaseWidgetState> {
  public constructor(props: Readonly<P>) {
    super(props);
    this.state = { loading: undefined } as S & BaseWidgetState;
  }

  public async componentDidMount() {
    this.setState({ ...(await this.getData()), loading: false });
  }

  public render() {
    const { root, header, body, footer } = this.styling();
    const showLoading = this.state.loading !== false && this.loading() !== undefined;
    return (
      <div className={mergeStyles(classNames.root, root)}>
        {this.header() && (
          <div className={mergeStyles(classNames.header, header)}>{this.header()}</div>
        )}
        {showLoading ? (
          this.loading()
        ) : (
          <>
            {this.body() !== undefined && <div className={body}>{this.body()}</div>}
            {this.footer() !== undefined && (
              <div className={mergeStyles(classNames.footer, footer)}>{this.footer()}</div>
            )}
          </>
        )}
      </div>
    );
  }

  protected async getData(): Promise<S> {
    return undefined;
  }

  protected header(): JSX.Element | undefined {
    return undefined;
  }

  protected body(): JSX.Element | undefined {
    return undefined;
  }

  protected footer(): JSX.Element | undefined {
    return undefined;
  }

  protected loading(): JSX.Element | undefined {
    return undefined;
  }

  protected styling(): IWidgetClassNames {
    return {};
  }
}

A seguir estão os métodos recomendados para substituir:

Métodos Função Recomendamos substituir
constructor() Invoca a inicial this.state e chama o construtor da super classe React.Component. Não
componentDidMount() Invoca depois que um componente é montado e atribui um valor à data propriedade do estado chamando o getData() método. Não
render() Invoca sempre que há uma atualização. O layout padrão dashboard é definido neste método. Não
getData() Invoca os dados necessários pelo widget. O valor retornado por esse método é definido como this.state.data. Sim
header() Invoca como é o cabeçalho do widget. Você pode optar por substituir esse método para personalizar um widget ou não, se não, o widget não terá um cabeçalho. Sim
body() Invoca como é o corpo do widget. Você pode optar por substituir esse método para personalizar um widget ou não, se não, o widget não terá um corpo. Sim
footer() Invoca como é o rodapé do widget. Você pode optar por substituir esse método para personalizar um widget ou não, se não for, o widget não terá um rodapé. Sim
loading() Invoca quando o widget está no processo de busca de dados. Se um indicador de carregamento for necessário, o método poderá retornar um JSX.Element que contém os componentes necessários para renderizar o indicador de carregamento. Sim
style() Invoca um objeto que define os nomes de classe para as diferentes partes do widget. Sim

Microsoft Graph Toolkit como conteúdo de widget

O Microsoft Graph Toolkit é um conjunto de componentes web renováveis e agnósticos da estrutura, que ajuda a acessar e trabalhar com o Microsoft Graph. Você pode usar o Microsoft Graph Toolkit com qualquer estrutura da Web ou sem uma estrutura.

Para usar o Microsoft Graph Toolkit como seu conteúdo de widget, siga estas etapas:

  1. Adicionar o recurso SSO ao seu aplicativo teams: o Microsoft Teams fornece função SSO (logon único) para um aplicativo obter o token de usuário do Teams conectado para acessar o Microsoft Graph. Para obter mais informações, consulte o recurso SSO para seu aplicativo do Teams.

  2. Instale pacotes necessários npm .

    Execute o seguinte comando em sua pasta de projeto tabs para instalar os pacotes necessários npm :

    npm install @microsoft/mgt-react @microsoft/mgt-teamsfx-provider
    
  3. Adicionar um novo widget do Graph Toolkit: crie um novo arquivo widget na pasta do projeto src/views/widgets , por exemplo, GraphWidget.tsx. Neste widget, orientaremos os usuários a consentir que nosso aplicativo acesse o Microsoft Graph e mostre a lista Todo do usuário usando o Microsoft Graph Toolkit.

    O código a seguir é um exemplo de uso do componente Todo do Microsoft Graph Toolkit no widget:

    import { Providers, ProviderState, Todo } from "@microsoft/mgt-react";
    import { TeamsFxProvider } from "@microsoft/mgt-teamsfx-provider";
    
    import { loginAction } from "../../internal/login";
    import { TeamsUserCredentialContext } from "../../internal/singletonContext";
    import { BaseWidget } from "@microsoft/teamsfx-react";
    
    interface IGraphWidgetState {
      needLogin: boolean;
    }
    
    export class GraphWidget extends Widget<any, IGraphWidgetState> {
      override body(): JSX.Element | undefined {
        return <div>{this.state.needLogin === false && <Todo />}</div>;
      }
    
      async componentDidMount() {
        super.componentDidMount();
    
        // Initialize TeamsFx provider
        const provider = new TeamsFxProvider(TeamsUserCredentialContext.getInstance().getCredential(), [
         "Tasks.ReadWrite",
    ]);
        Providers.globalProvider = provider;
    
        // Check if user is signed in
        if (await this.checkIsConsentNeeded()) {
          await loginAction(["Tasks.ReadWrite"]);
    }
    
    // Update signed in state
    Providers.globalProvider.setState(ProviderState.SignedIn);
    this.setState({ needLogin: false });
    
      }
    
      /**
    
      * Check if user needs to consent
      * @returns true if user needs to consent
      */
    
      async checkIsConsentNeeded() {
        let needConsent = false;
        try {
          await TeamsUserCredentialContext.getInstance().getCredential().getToken(["Tasks.ReadWrite"]);
        } catch (error) {
          needConsent = true;
        }
        return needConsent;
      }
    }
    

    Você pode usar componentes alternativos do Microsoft Graph Toolkit em seu widget. Para obter mais informações, confira Kit de Ferramentas do Microsoft Graph.

  4. Adicione o widget ao layout dashboard. Inclua o novo widget no arquivo dashboard.

    ...
    export default class YourDashboard extends BaseDashboard<any, any> {
      ...
      override layout(): undefined | JSX.Element {
        return (
          <>
            <GraphWiget />
          </>
        );
      }
      ...
    }
    

Agora, inicie ou atualize seu aplicativo teams, você verá o novo widget usando o Microsoft Graph Toolkit.

API do Graph chamada

O Microsoft API do Graph é uma API Web que você pode usar para se comunicar com a nuvem da Microsoft e outros serviços. Aplicativos personalizados podem usar a API do Microsoft Graph para se conectar aos dados e usá-los em aplicativos personalizados para aprimorar a produtividade organizacional.

Antes de implementar sua lógica de chamada API do Graph, é necessário habilitar o SSO para seu projeto de dashboard. Para obter mais informações, confira Adicionar logon único ao aplicativo do Teams.

Para adicionar uma chamada API do Graph:

Chamar API do Graph do front-end (usar permissões delegadas)

Se você quiser chamar um API do Graph na guia front-end, siga estas etapas:

  1. Para obter o nome do escopo de permissão associado ao API do Graph você pretende invocar, consulte API do Graph.

  2. Crie um cliente graph adicionando o escopo relacionado ao API do Graph que você deseja chamar.

    let credential: TeamsUserCredential;  
    credential = TeamsUserCredentialContext.getInstance().getCredential();
    const graphClient: Client = createMicrosoftGraphClientWithCredential(credential, scope);
    
  3. Chame o API do Graph e analise a resposta em um determinado modelo.

    try {
      const graphApiResult = await graphClient.api("<GRAPH_API_PATH>").get();
      // Parse the graphApiResult into a Model you defined, used by the front-end.
    } catch (e) {}
    

Chamar API do Graph do back-end (usar permissões de aplicativo)

Se você quiser chamar um API do Graph do back-end, siga estas etapas:

  1. Permissões de aplicativo de consentimento
  2. Adicionar uma função do Azure
  3. Adicionar sua lógica na função do Azure
  4. Chame a função do Azure do front-end

Para consentir permissões de aplicativo, siga estas etapas:

  1. Acesse o portal do Azure.
  2. Selecione Azure Active Directory.
  3. Selecione Registros de aplicativo no painel esquerdo.
  4. Selecione seu aplicativo dashboard.
  5. Selecione permissões de API no painel esquerdo.
  6. Selecione Adicionar permissão.
  7. Selecione Microsoft Graph.
  8. Selecione Permissões de aplicativos.
  9. Encontre as permissões necessárias.
  10. Selecione o botão Adicionar permissões na parte inferior.
  11. Selecione ✔Conceder consentimento do administrador.
  12. Selecione o botão Sim para concluir o consentimento do administrador.

Adicionar uma função do Azure

No painel esquerdo do Visual Studio Code, vá para o Teams Toolkit>Adicionando recursos>Azure Functions e insira o nome da função.

A captura de tela mostra a seleção de Azure Functions.

Para obter mais informações sobre como adicionar uma Função do Azure ao seu projeto, confira integrar Azure Functions ao aplicativo teams.

Adicionar sua lógica na função do Azure

index.ts/index.ts Na pasta chamada Função do Azure, você pode adicionar sua lógica que contém chamadas de back-end API do Graph com permissões de aplicativo. Consulte o seguinte snippet de código:

/**
 * This function handles requests from teamsfx client.
 * The HTTP request should contain an SSO token queried from Teams in the header.
 * Before triggering this function, teamsfx binding would process the SSO token and generate teamsfx configuration.
 *
 * You should initializes the teamsfx SDK with the configuration and calls these APIs.
 *
 * The response contains multiple message blocks constructed into a JSON object, including:
 * - An echo of the request body.
 * - The display name encoded in the SSO token.
 * - Current user's Microsoft 365 profile if the user has consented.
 *
 * @param {Context} context - The Azure Functions context object.
 * @param {HttpRequest} req - The HTTP request.
 * @param {teamsfxContext} TeamsfxContext - The context generated by teamsfx binding.
 */
export default async function run(
  context: Context,
  req: HttpRequest,
  teamsfxContext: TeamsfxContext
): Promise<Response> {
  context.log("HTTP trigger function processed a request.");

  // Initialize response.
  const res: Response = {
    status: 200,
    body: {},
  };

  // Your logic here.

  return res;
}

Chame a função do Azure do front-end

Chame a função do Azure pelo nome da função. Consulte o seguinte snippet de código para chamar a função do Azure:

const functionName = process.env.REACT_APP_FUNC_NAME || "myFunc";
export let taskName: string;

export async function callFunction(params?: string) {
  taskName = params || "";
  const credential = TeamsUserCredentialContext.getInstance().getCredential();
  if (!credential) {
    throw new Error("TeamsFx SDK is not initialized.");
  }
  try {
    const apiBaseUrl = process.env.REACT_APP_FUNC_ENDPOINT + "/api/";    
    const apiClient = createApiClient(
      apiBaseUrl,
      new BearerTokenAuthProvider(async () => (await credential.getToken(""))!.token)
    );
    const response = await apiClient.get(functionName);
    return response.data;
  } catch (err: unknown) {
    ...
  }
}

Para saber mais, veja:

Insira o Power BI para dashboard

Para inserir o Power BI no dashboard, consulte o cliente do Power BI reagir.

Guias passo a passo

Siga o guia passo a passo para criar um dashboard e aprenda a adicionar um widget e API do Graph chamada ao dashboard.

Confira também