Looker コンポーネントを使用してタブ付きダッシュボードを構築する

UI コンポーネントが埋め込みアプリケーションを拡張する簡単な例は、UI コンポーネントを使用してダッシュボードのタブ ナビゲーションを作成することです。

タブ化されたインターフェースを備えたダッシュボードの例。

次の例では、Looker の拡張フレームワークを使用して構築された基本的な TypeScript 拡張機能にタブ付きダッシュボードを追加します。

この例を試すには、設定が要件を満たしていることを確認してから、次の手順を行ってください。

  1. 基本的な TypeScript 拡張機能を作成します。
  2. ダッシュボードを接続して保存するためのファイル src/Dashboards.tsx を作成します。
  3. Tabs コンポーネントを保存するためのファイル src/Tabs.tsx を作成します。
  4. src/App.tsx にある HelloWorld の参照を置き換えます。
  5. 埋め込みの権限で manifest.lkml ファイルを更新します。
  6. Looker インスタンスに拡張機能を公開します。

要件

始める前に、いくつかの要素が必要になります。

  • 拡張フレームワークが有効になっている Looker インスタンスにアクセスできる必要があります。
  • develop 権限が必要です。
  • Looker 内には、UI タブ内に配置するために、ユーザー定義のダッシュボードが複数存在している必要があります。
  • 拡張機能のフレームワークを構築する場合でも、独自のスタンドアロンの React アプリケーションを構築する場合でも、Looker の API で認証し、Looker SDK オブジェクトにアクセスできることが重要です。詳細については、Looker API 認証または拡張機能フレームワークをご覧ください。
  • この例では、Looker Embed SDK を使用します。Embed SDK をインスタンスに対して実行できるようにするには、[Admin] パネルの [Embed] ページ内にある [Embed Domain 許可リスト] に http://localhost:8080 を含める必要があります。
  • Looker コンポーネントの NPM パッケージがインストールされていることを確認してください。コンポーネント パッケージのインストールと使用方法については、GitHubNPM にある README ドキュメントをご覧ください。

ステップ 1: 基本的な TypeScript 拡張機能を作成する

ドキュメント ページ Looker 拡張機能のビルドの概要の手順に沿って拡張機能をビルドします。その拡張機能を TypeScript 拡張機能にするには、次の変更を行います。

ステップ 2: src/Dashboards.tsx ファイルを作成し、ダッシュボードに接続して保存する

新しい拡張機能の src ディレクトリに Dashboards.tsx ファイルを作成します。このファイルは、Looker 内で作成したダッシュボードを接続して保存します。

ファイル内に、次のコードを貼り付けます。このコードは 3 つのダッシュボード オブジェクトを作成し、それらを ID で指定します。必要に応じて、作成するダッシュボード オブジェクトの数を変更して作成できます。

コードには、インスタンス URL(https://mycompany.looker.com)が 3 か所あります。これを Looker インスタンスの URL に変更します。

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%;
 }
`;

前述のコード例では、次のことが発生します。

  • import ステートメントでは、必要な依存関係が取得されます。

    import React, { useCallback } from "react";
    import { LookerEmbedSDK } from "@looker/embed-sdk";
    import styled from "styled-components";
    
  • 次のコードブロックでは、EmbeddedDashboard1 オブジェクトが作成されます。このオブジェクトは、ダッシュボードの iframe を含む EmbedContainer オブジェクトです。その iframe は、渡されたダッシュボード ID を使用して Looker Embed SDK から生成されます。必ず https://mycompany.looker.com/ を Looker インスタンス URL に更新してください。

    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>;
    };
    
  • 次の 2 つのコードブロックは、EmbeddedDashboard2EmbeddedDashboard3 に対してこのプロセスを繰り返します。もう一度、https://mycompany.looker.com/ を Looker インスタンス URL に更新してください。

  • 最後のブロックは、EmbedContainer をスタイル設定します。

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

ステップ 3: Tabs コンポーネントを保存する src/Tabs.tsx ファイルを作成する

新しい拡張機能の src ディレクトリに Tabs.tsx ファイルを作成します。このファイルには Tabs コンポーネントが保存され、各ダッシュボードの Looker ダッシュボード ID が参照されます。

このファイル内に、次のコードを貼り付けます(このセクションでは、コードに続いてその動作について説明します)。

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>
)

前述のコード例では、次のことが発生します。

  • import ステートメントによって、必要な依存関係とコンポーネントと、Dashboards.tsx ファイルで作成された EmbeddedDashboard オブジェクトが取り込まれます。

    import React from "react";
    import { ComponentsProvider, Tabs2, Tab2 } from "@looker/components";
    import { EmbeddedDashboard1, EmbeddedDashboard2, EmbeddedDashboard3,
    } from "./Dashboard";
    
  • export ステートメントでは、Tabs オブジェクトを他のコンポーネントへインポートできるようにしています。

    export const Tabs = () => (
    
  • ComponentsProvider は、テーマ設定を支援するために、個別のコンポーネントにラップしています。

    <ComponentsProvider>
    </ComponentsProvider>
    
  • Tabs2コンポーネントとその子コンポーネント(Tab2)を使用するには、3 つのタブを作成し、それを 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>
    
    • Tab2id プロパティでは、一意のタブ ID を受け取ります。必要に応じて、環境に応じて ID を更新します。
    • label プロパティは、各タブに表示されるラベルを受け取ります。使用しているダッシュボードに応じて ID を更新します。
    • Tab2 タグ内に配置された文字列は、そのタブのコンテンツ領域の上部に表示されます。必要に応じて文字列を更新または削除します。
    • EmbeddedDashboard1EmbeddedDashboard1EmbeddedDashboard1 オブジェクトがタブ内に配置されます。id プロパティは、そのタブ内に埋め込まれたダッシュボードの ID を受け取ります。独自のタブ付きダッシュボードを構築する場合は、この値を、使用するダッシュボードのダッシュボード ID に置き換えます。数値のダッシュボード ID は、URL の dashboards/ の後のにあります。たとえば、URL が https://example.looker.com/dashboards/61?Recording+Date=10+weeks&Country=US の場合、ダッシュボード ID は 61 になります。

ステップ 4: src/App.tsx の HelloWorld 参照を置換する

src ディレクトリの App.tsx ファイルに移動します。HelloWorld インポート ステートメントを削除します。

import { HelloWorld } from './HelloWorld'

それを次の形に置き換えます。

import { Tabs } from './Tabs'

さらに、src/App.tsx ファイルで、<HelloWorld/><Tabs/> に置き換えます。

HelloWorld.tsx ファイルは使用しなくなるため、このディレクトリから削除することもできます。

ステップ 5: 埋め込みの権限で manifest.lkml ファイルを更新する

LookML プロジェクトで、manifest.lkml ファイルの entitlements セクションに、次の権限を追加します。

use_embeds: yes

manifest.lkml ファイルは、次のようになります。

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
  }
}

これで、左側のナビゲーション パネルで、[Applications] フォルダ内にある拡張機能に移動できます。yarn develop でローカル開発用サーバーを起動すると、タブ付きの埋め込みダッシュボードが表示されます。

ステップ 6: Looker インスタンスに拡張機能を公開する

他の Looker ユーザーに拡張機能を表示するには、次の手順で Looker インスタンスに拡張機能を公開します。

  1. 開発用サーバーを実行している状態で、localhost:8080/bundle.js に移動します。
  2. ブラウザ ウィンドウのコンテンツを、.js ファイルとしてローカルの PC に保存します。
  3. 開発モードになっていることを確認し、.js ファイルを拡張機能プロジェクトにドラッグ&ドロップします。変更を保存します。
  4. manifest.lkml ファイルで、url: "http://localhost:8080/bundle.js" の行をコメントにします。
  5. manifest.lkml ファイルで、# file: "bundle.js" の行のコメントを解除し、ファイル名がプロジェクトにアップロードした .js ファイルのファイル名と一致することを確認します。変更を保存します。
  6. 変更を commit してデプロイします。

デプロイ後は、ローカル開発用サーバーを起動しなくても拡張機能を確認できます。Looker インスタンスのユーザーは、左側のナビゲーション パネルで、Applications フォルダに移動して拡張機能を確認できます。