Crea un panel con pestañas con componentes de Looker

Un ejemplo sencillo de cómo los componentes de la IU pueden mejorar una aplicación incorporada es usarlos para crear una navegación con pestañas para los paneles:

Panel de ejemplo con una interfaz con pestañas

En el siguiente ejemplo, se agregan paneles con pestañas a una extensión básica de TypeScript que se compiló con el framework de extensiones de Looker.

Para trabajar en este ejemplo, asegúrate de que tu configuración cumpla con los requisitos y, luego, sigue estos pasos:

  1. Compila una extensión básica de TypeScript.
  2. Crea el archivo src/Dashboards.tsx para conectar y almacenar paneles.
  3. Crea el archivo src/Tabs.tsx para almacenar el componente Tabs.
  4. Reemplaza la referencia de HelloWorld en src/App.tsx.
  5. Actualiza el archivo manifest.lkml con derecho de incorporación.
  6. Publicar la extensión en tu instancia de Looker

Requisitos

Necesitarás algunos elementos antes de comenzar:

Paso 1: Compila una extensión básica de TypeScript

Sigue las instrucciones de la página de documentación Introducción a la compilación de una extensión de Looker para compilar una extensión. Para convertir la extensión en una extensión de TypeScript, usa las siguientes modificaciones:

Paso 2: Crea el archivo src/Dashboards.tsx para conectar y almacenar paneles

Dentro del directorio src de tu extensión nueva, crea un archivo Dashboards.tsx. Este archivo se conectará y almacenará los paneles que creaste en Looker.

Dentro del archivo, pega el siguiente código. Este código crea tres objetos de panel y los especifica por ID. Puedes crear más o menos objetos de panel, según tus necesidades.

Hay tres ubicaciones en el código de una URL de instancia, https://mycompany.looker.com. Cámbiala por la URL de tu instancia de Looker.

import React, { useCallback } from "react";
import { LookerEmbedSDK } from "@looker/embed-sdk";
import styled from "styled-components";

export const EmbeddedDashboard1 = (props: { id: number | string }) => {
 const [dashboard, setDashboard] = React.useState();
 const setupDashboard = (dashboard: any) => {
   setDashboard(dashboard);
 };
 const embedCtrRef = useCallback((el) => {
   const hostUrl = "https://mycompany.looker.com/";
   if (el && hostUrl) {
     el.innerHTML = "";
     LookerEmbedSDK.init(hostUrl);
     LookerEmbedSDK.createDashboardWithId(props.id)
       .withNext()
       .appendTo(el)
       .build()
       .connect()
       .then(setupDashboard)
       .catch((error) => {
         console.error("Connection error", error);
       });
   }
 }, []);
 return <EmbedContainer ref={embedCtrRef}></EmbedContainer>;
};

export const EmbeddedDashboard2 = (props: { id: number }) => {
 const [dashboard, setDashboard] = React.useState();
 const setupDashboard = (dashboard: any) => {
   setDashboard(dashboard);
 };
 const embedCtrRef = useCallback((el) => {
   const hostUrl = "https://mycompany.looker.com/";
   if (el && hostUrl) {
     el.innerHTML = "";
     LookerEmbedSDK.init(hostUrl);
     LookerEmbedSDK.createDashboardWithId(props.id)
       .withNext()
       .appendTo(el)
       .build()
       .connect()
       .then(setupDashboard)
       .catch((error) => {
         console.error("Connection error", error);
       });
   }
 }, []);
 return <EmbedContainer ref={embedCtrRef}></EmbedContainer>;
};

export const EmbeddedDashboard3 = (props: { id: number }) => {
 const [dashboard, setDashboard] = React.useState();
 const setupDashboard = (dashboard: any) => {
   setDashboard(dashboard);
 };
 const embedCtrRef = useCallback((el) => {
   const hostUrl = "https://mycompany.looker.com/";
   if (el && hostUrl) {
     el.innerHTML = "";
     LookerEmbedSDK.init(hostUrl);
     LookerEmbedSDK.createDashboardWithId(props.id)
       .withNext()
       .appendTo(el)
       .build()
       .connect()
       .then(setupDashboard)
       .catch((error) => {
         console.error("Connection error", error);
       });
   }
 }, []);

 return <EmbedContainer ref={embedCtrRef}></EmbedContainer>;
};

export const EmbedContainer = styled.div`
 width: 100%;
 height: 95vh;
 & > iframe {
   width: 100%;
   height: 100%;
 }
`;

En el ejemplo de código anterior, sucede lo siguiente:

  • Las sentencias de importación incorporan las dependencias necesarias.

    import React, { useCallback } from "react";
    import { LookerEmbedSDK } from "@looker/embed-sdk";
    import styled from "styled-components";
    
  • El siguiente bloque de código crea un objeto EmbeddedDashboard1, que es un objeto EmbedContainer que contiene un iframe del panel. El iframe se genera desde el SDK de incorporación de Looker con el ID del panel que se le pasa. Asegúrate de actualizar https://mycompany.looker.com/ a la URL de tu instancia de Looker.

    export const EmbeddedDashboard1 = (props: { id: number | string }) => {
    const [dashboard, setDashboard] = React.useState();
    const setupDashboard = (dashboard: any) => {
      setDashboard(dashboard);
    };
    const embedCtrRef = useCallback((el) => {
      const hostUrl = "https://mycompany.looker.com/";
      if (el && hostUrl) {
        el.innerHTML = "";
        LookerEmbedSDK.init(hostUrl);
        LookerEmbedSDK.createDashboardWithId(props.id)
          .withNext()
          .appendTo(el)
          .build()
          .connect()
          .then(setupDashboard)
          .catch((error) => {
            console.error("Connection error", error);
          });
      }
    }, []);
    return <EmbedContainer ref={embedCtrRef}></EmbedContainer>;
    };
    
  • Los siguientes dos bloques de código repiten este proceso para EmbeddedDashboard2 y EmbeddedDashboard3. Una vez más, asegúrate de actualizar https://mycompany.looker.com/ a la URL de tu instancia de Looker.

  • El bloque final diseña el EmbedContainer.

      export const EmbedContainer = styled.div`
        width: 100%;
        height: 95vh;
        & > iframe {
          width: 100%;
          height: 100%;
        }
    `;
    

Paso 3: Crea el archivo src/Tabs.tsx para almacenar el componente Tabs

Dentro del directorio src de tu extensión nueva, crea un archivo Tabs.tsx. Este archivo almacena el componente Tabs y hace referencia al ID del panel de Looker para cada panel.

Dentro de ese archivo, pega el siguiente código (en la sección que sigue, se explica lo que hace el código):

import React from "react";
import { ComponentsProvider, Tabs2, Tab2 } from "@looker/components";
import { EmbeddedDashboard1, EmbeddedDashboard2, EmbeddedDashboard3,
} from "./Dashboards";

export const Tabs = () => (
 <ComponentsProvider>
   <Tabs2>
     <Tab2 id="5" label="Order Analysis Dashboard">
      Order data from the last 12 months
       <EmbeddedDashboard1 id={5} />
     </Tab2>
     <Tab2 id="2" label="Inventory Dashboard">
       Current global inventory
       <EmbeddedDashboard2 id={2} />
     </Tab2>
     <Tab2 id="7" label="Customer Dashboard">
       Anonymized customer data
       <EmbeddedDashboard3 id={7} />
     </Tab2>
   </Tabs2>
 </ComponentsProvider>
)

En el ejemplo de código anterior, sucede lo siguiente:

  • Las sentencias de importación incorporan las dependencias y los componentes necesarios, así como los objetos EmbeddedDashboard que se crearon en el archivo Dashboards.tsx.

    import React from "react";
    import { ComponentsProvider, Tabs2, Tab2 } from "@looker/components";
    import { EmbeddedDashboard1, EmbeddedDashboard2, EmbeddedDashboard3,
    } from "./Dashboard";
    
  • La sentencia de exportación hace que el objeto Tabs esté disponible para importarse a otros componentes.

    export const Tabs = () => (
    
  • El ComponentsProvider une componentes individuales para ayudar con los temas.

    <ComponentsProvider>
    </ComponentsProvider>
    
  • El componente Tabs2 y su componente secundario, Tab2, crean tres pestañas y las vinculan a los paneles de Looker.

     <Tabs2>
     <Tab2 id="5" label="Order Analysis Dashboard">
      Order data from the last 12 months
       <EmbeddedDashboard1 id={5} />
     </Tab2>
     <Tab2 id="2" label="Inventory Dashboard">
       Current global inventory
       <EmbeddedDashboard2 id={2} />
     </Tab2>
     <Tab2 id="7" label="Customer Dashboard">
       Anonymized customer data
       <EmbeddedDashboard3 id={7} />
     </Tab2>
    </Tabs2>
    
    • La propiedad id de Tab2 acepta un ID de pestaña único. Actualiza el ID según sea necesario para tu entorno.
    • El prop label acepta la etiqueta que aparecerá en cada pestaña. Actualiza el ID según corresponda para el panel que estás usando.
    • Una cadena que se coloca dentro de las etiquetas Tab2 aparecerá en la parte superior del área de contenido de esa pestaña. Actualiza o quita la cadena según sea necesario.
    • Los objetos EmbeddedDashboard1, EmbeddedDashboard1 y EmbeddedDashboard1 se colocan dentro de la pestaña. Sus propiedades de id aceptan el ID del panel que se incorporará dentro de esa pestaña. Cuando crees tu propio panel con pestañas, reemplaza este valor por el ID del panel que deseas usar. Puedes encontrar el ID numérico del panel en la URL después de dashboards/. Por ejemplo, si la URL es https://example.looker.com/dashboards/61?Recording+Date=10+weeks&Country=US, el ID del panel sería 61.

Paso 4: Reemplaza la referencia de HelloWorld en src/App.tsx

Navega a tu archivo App.tsx en el directorio src. Quita la sentencia de importación HelloWorld:

import { HelloWorld } from './HelloWorld'

y reemplázala por lo siguiente:

import { Tabs } from './Tabs'

Además, en el archivo src/App.tsx, reemplaza <HelloWorld/> por <Tabs/>.

De manera opcional, también puedes borrar el archivo HelloWorld.tsx de este directorio, ya que ya no lo usarás.

Paso 5: Actualiza el archivo manifest.lkml con el derecho de incorporación

Agrega el siguiente derecho a la sección de derechos del archivo manifest.lkml en tu proyecto de LookML:

use_embeds: yes

El archivo manifest.lkml debería verse de la siguiente manera:

application: name {
  label: "label"
  url: "http://localhost:8080/bundle.js"
  # file: "bundle.js
  entitlements: {
    core_api_methods: ["me"] #Add more entitlements here as you develop new functionality
    use_embeds: yes
  }
}

Ahora puedes navegar a tu extensión, que aparece en la carpeta Applications en el panel de navegación izquierdo. Si iniciaste el servidor de desarrollo local con yarn develop, puedes ver los paneles con pestañas incorporados.

Paso 6: Publica la extensión en tu instancia de Looker

Para mostrar la extensión a otros usuarios de Looker, sigue estos pasos para publicarla en tu instancia de Looker:

  1. Con el servidor de desarrollo en ejecución, navega a localhost:8080/bundle.js.
  2. Guarda el contenido de la ventana del navegador de manera local en tu computadora como un archivo .js.
  3. Asegúrate de que estás en modo de desarrollo y, luego, arrastra y suelta el archivo .js en tu proyecto de extensión. Guarda los cambios.
  4. En el archivo manifest.lkml, comenta la línea url: "http://localhost:8080/bundle.js".
  5. En el archivo manifest.lkml, quita el comentario de la línea # file: "bundle.js" y asegúrate de que el nombre del archivo coincida con el del archivo .js que subiste a tu proyecto. Guarda los cambios.
  6. Confirma y, luego, implementa los cambios.

Una vez que se implemente, ya no necesitarás iniciar el servidor de desarrollo local para ver la extensión, y los usuarios de tu instancia de Looker deberían poder verla si navegan a ella dentro de la carpeta Applications en el panel de navegación izquierdo.