AirtableとReactを使用したライブダッシュボードの作成

公開: 2022-03-11

企業が大企業であろうと新進の新興企業であろうと、ユーザーや顧客からデータを収集し、そのデータを報告または視覚化することは、ビジネスにとって非常に重要です。

私は最近、ブラジルに拠点を置く遠隔医療のスタートアップと仕事をしました。 その使命は、患者を医療専門家や医療コーチに接続することにより、遠隔医療と監視を提供することです。 中心的な必要性は、コーチと医療専門家が患者の情報と特定の状況に関連する最も重要な指標であるダッシュボードを簡単に確認するためのインターフェースを作成することでした。

TypeformとAirtableを入力します。

タイプフォーム

Typeformは、調査を完了するユーザーがレスポンシブWebエクスペリエンスを利用できるようにする、頼りになるデータ収集ツールの1つです。 また、特に組み合わせた場合に、調査をよりインテリジェントにするいくつかの機能が付属しています。

  • ロジックジャンプ
  • 隠しフィールド

調査は、非表示フィールドの値を事前にシードできるURLを介して共有できます。これを使用して、ロジックジャンプを実装し、リンクを使用するユーザーの調査の動作を変更できます。

Airtableの使用

Airtableは、スプレッドシートとデータベースのハイブリッドであり、コラボレーション型クラウドプラットフォームです。 ポイントアンドクリック機能に重点を置いているため、技術者以外のユーザーはコーディングせずに構成できます。 Airtableには、あらゆるビジネスやプロジェクトで多数のユースケースがあります。

Airtable Baseは、次の目的で使用できます。

  • CRM (顧客関係管理)
  • HRIS (人事情報システム)
  • プロジェクト管理
  • コンテンツプランニング
  • イベント企画
  • ユーザーフィードバック

さらに多くの潜在的なユースケースがあります。 ここでAirtableのケーススタディを調べることができます。

Airtableに慣れていない場合、概念データモデルは次のように分類されます。

  • ワークスペース-ベースで構成
  • ベース-テーブルで構成
  • -フィールド(列)と行で構成されます
  • ビュー-オプションのフィルターと削減されたフィールドを使用したテーブルデータのパースペクティブ
  • フィールド-フィールドタイプを持つテーブルの列。 フィールドタイプの詳細については、ここを参照してください

使い慣れたスプレッドシート機能を備えたクラウドホスト型データベースを提供する以外に、プラットフォームが非常に強力である理由のいくつかを次に示します。

Airtableを使用している技術ユーザーと非技術ユーザーの描写。

技術者以外のユーザーのために、Airtableは以下を提供します。

  • 使いやすいフロントエンドインターフェイス
  • ポイントアンドクリック構成で作成できる自動化により、電子メールの送信、データの行の処理、カレンダーでの予定のスケジュール設定などを行うことができます。
  • チームが同じベースとテーブルで共同作業できるようにする複数のタイプのビュー
  • マーケットプレイスからインストールして基地を過給できるAirtableアプリ

開発者向けに、Airtableは以下を提供します。

  • 十分に文書化されたバックエンドAPI
  • 開発者がBase内のアクションを自動化できるようにするスクリプト環境
  • Airtable環境内で実行されるカスタム開発されたスクリプトをトリガーできる自動化により、自動化の機能が拡張されます

Airtableについて詳しくは、こちらをご覧ください。

はじめに:TypeformからAirtableへ

タイプフォーム調査はクライアントによってすでに構成されており、次のステップは、そのデータがAirtableに到達し、ダッシュボードに変換される方法を計画することでした。 データベース上にダッシュボードを作成する際に考慮すべき多くの質問があります。データをどのように構造化する必要がありますか? 視覚化の前にどのデータを処理する必要がありますか? BaseをGoogleSheetsと同期して、Google Data Studioを使用する必要がありますか? 別のサードパーティツールをエクスポートして見つける必要がありますか?

開発者にとって幸いなことに、Airtableはデータ処理ステップを処理するための自動化とスクリプトを提供するだけでなく、Airtableアプリを使用してAirtableベース上にカスタムアプリケーションとインターフェイスを構築することも可能にしました。

Airtableのカスタムアプリ

Airtableのカスタムアプリは、2018年の初めにAirtable Blocks SDKがリリースされて以来存在しており、最近、Appsに名前が変更されました。 Blocksのリリースは巨大で、Airtableが言うように、クリエイターは「無限に再結合可能なレゴキット」を開発できるようになりました。

最近では、アプリの変更に伴い、AirtableMarketplaceでアプリを公開することも可能になりました。

Airtable Appsは、ニーズに合わせて調整できる無限に再結合可能なレゴキットを企業に提供します。

Airtableでカスタムアプリを構築するには、JavaScript開発者は、ユーザーインターフェイスを構築するための最も人気のあるJavaScriptライブラリの1つであるReactの使用方法を知っている必要があります。 Airtableは、機能的なReactコンポーネントとフックのコンポーネントライブラリを提供します。これは、一貫性のあるUIを迅速に構築し、アプリとそのコンポーネント内の状態を管理する方法を決定するのに非常に役立ちます。

詳細についてはAirtableの入門記事を、アプリの例についてはGitHubのAirtableをご覧ください。

Airtableダッシュボードの要件

クライアントチームとダッシュボードのモックアップを確認した後、使用するデータの種類が明確になりました。 ダッシュボードにテキストとして表示される一連のダッシュボードコンポーネントと、時間の経過とともに追跡できるさまざまなメトリックのグラフが必要になります。

コーチと医療専門家は、患者ごとにカスタムダッシュボードを作成できる必要があったため、グラフを追加および削除するための柔軟な方法が必要でした。 選択した患者に関係なく、各患者に関連するその他の静的データが表示されます。

この場合、ダッシュボードセクションは次のように要約されます。

  • 一般情報-患者名、電子メール、電話番号、連絡先、生年月日、年齢
  • 目的-調査結果に基づく患者の目標
  • いくつかの統計-BMI、身長、体重
  • 薬の使用-患者がすでに使用しているすべての処方薬を一覧表示
  • 病状の家族歴-特定の病状の診断に役立ちます
  • チャート-Airtableダッシュボードユーザーがチャートを追加し、時間の経過とともに視覚化するメトリックを構成できるセクション

Airtableダッシュボードのモックアップを示す画像。

チャートを除くすべてのセクションにアプローチする1つの方法は、目的、薬の使用、および家族歴のすべての列をダッシュ​​ボードにハードコーディングすることです。 ただし、これでは、開発者がカスタムアプリを更新しなくても、クライアントチームがTypeform調査に新しい質問を追加したり、Airtableテーブルに新しい列を追加してダッシュボードにそのデータを表示したりすることはできません。

この課題に対するよりエレガントで拡張可能なソリューションは、特定のダッシュボードセクションに関連する列にタグを付け、テーブルモデルとフィールドモデルを使用するときにAirtableが公開するメタデータを使用してそれらの列を取得する方法を見つけることでした。

これは、ユーザーに表示されるダッシュボードセクションに関連するテーブルの列にタグを付ける場所としてフィールドの説明を使用して実現されました。 次に、Baseの作成者の役割を持つユーザー(管理者)のみが、ダッシュボードに表示される内容を変更するためにこれらのフィールドの説明を変更できるようにすることができました。 このソリューションを説明するために、主に一般情報の項目とチャートの表示方法に焦点を当てます。

#TAG#システムの作成

ダッシュボードセクションを考えると、一部のセクションに再利用可能なタグを作成し、特定の列に特定のタグを作成することは理にかなっています。 患者名、電子メール、電話番号などの項目については、各フィールドの説明にそれぞれ#NAME #NAME##EMAIL# 、および#PHONE#が追加されました。 これにより、次のようにテーブルメタデータを介してその情報を取得できるようになります。

 const name = table ? table.fields.filter(field => field.description?.includes("#NAME#"))

多くのタグ付き列から描画する必要があるダッシュボードの領域については、ダッシュボードセクションごとに次のタグがあります。

  • OBJ-目的
  • FAM-家族の歴史
  • MED-薬の使用法
  • CAN-がんに特有の家族歴
  • チャート-チャートを追加するためにソースする必要のある列。 数量でなければなりません

さらに、テーブル内の列の名前をダッシュ​​ボードで受け取るラベルから分離することが重要でした。そのため、 #TAG#を受け取ったものはすべて、フィールドの説明で2つの#LABEL#タグを受け取ることができます。 。 フィールドの説明は次のようになります。

フィールドの説明でのタグの使用を示すスクリーンショット。

#LABEL#タグが欠落している場合は、テーブルの列名を表示します。

前のコード例でフィールドを取得した後、次のような単純な関数を使用して、説明で設定されたラベルを解析できます。

 // utils.js export const setLabel = (field, labelTag = "#LABEL#") => { const labelTags = (field.description?.match(new RegExp(labelTag, "g")) || []).length; let label; if (labelTags === 2) label = field.description?.split(`${labelTag}`)[1]; if (!label || label?.trim() === '') label = field.name; return {...field, label, name: field.name, description: field.description}; }

この#TAG#システムを使用して、次の3つの主要なことを実現します。

  • 表の列名(フィールド)は、必要に応じて変更できます。
  • ダッシュボードのデータのラベルは、列名とは異なる場合があります。
  • 目的、薬の使用法、家族歴、およびグラフのダッシュボードセクションは、コード行に触れることなくクライアントチームが更新できます。

Airtableの永続的な状態

Reactでは、状態を使用し、状態が変化した場合にそのコンポーネントを再レンダリングするために、それを小道具としてコンポーネントに渡します。 通常、これはダッシュボードコンポーネントに燃料を供給するAPI呼び出しに関連付けられていますが、Airtableにはすでにすべてのデータがあり、表示している患者に基づいて表示内容をフィルタリングする必要があります。 さらに、状態を使用すると、ダッシュボード自体の更新後もデータが保持されません。

では、ダッシュボードをフィルタリングしたままにするために、更新後も値を保持するにはどうすればよいでしょうか。 幸い、Airtableは、ダッシュボードにアプリをインストールするためのKey-Valueストアを維持するuseGlobalConfigと呼ばれるフックを提供します。 ダッシュボードコンポーネントに燃料を供給するためにアプリが読み込まれたときに、このKey-Valueストアから値を取得するロジックを実装する必要があります。

useGlobalConfigフックを使用することでさらに便利なのは、値が設定されると、ダッシュボードコンポーネントとその子コンポーネントが再レンダリングされるため、通常のReact実装で状態変数を使用するのと同じようにグローバル構成を使用できることです。

チャートの紹介

Airtableは、Chart.js(chart-ception)のReactラッパーであるReactChartsを使用するSimpleChartAppでチャートの例を提供します。

Simple Chartアプリでは、アプリ全体に対して1つのグラフがありますが、Dashboardアプリでは、ユーザーが自分のダッシュボードに自分のグラフを追加したり、自分のダッシュボードから自分のグラフを削除したりできる必要があります。 さらに、クライアントチームとの話し合いでは、特定の指標が同じチャートでより適切に表示されるようです(拡張期血圧と収縮期血圧の測定値など)。

これにより、取り組むべき次の項目があります。

  • 各ユーザーのグラフの永続的な状態(またはGlobal Configを使用するとさらに良い)
  • チャートごとに複数のメトリックを許可する

ここで、Global Configの機能が役立ちます。これは、Key-Valueストアを使用して、選択したメトリックやチャートのリストに関するその他の情報を維持できるためです。 UIでグラフを構成すると、グローバル構成の更新により、グラフコンポーネント自体が再レンダリングされます。 ダッシュボードのチャートセクションについては、ダッシュボードのcharts.jsと単一のchart.jsに焦点を当てた、参照用のコンポーネントの要点を以下に示します。

各チャートに渡されるテーブルは、フィールドを見つけるためのメタデータに使用されるものですが、渡されるレコードは、 dashboard_charts/index.jsをインポートするトップレベルのダッシュボードコンポーネントで選択された患者によってすでにフィルタリングされています。

グラフのドロップダウンにオプションとしてリストされているフィールドは、前述の#CHART#タグを使用して取得され、この行はuseEffectフックに含まれていることに注意してください。

 // single_chart/index.js … useEffect(() => { (async () => { ... if (table) { const tempFieldOptions = table.fields.filter(field => field.description?.includes('#CHART#')).map(field => { return { ...setLabel(field), value: field.id } }); setFieldSelectOptions([...tempFieldOptions]); } })(); }, [table, records, fields]); ...

上記のコードは、前に参照したsetLabel関数を#TAG#とともに使用して、 #LABEL#タグで提供されるものを追加し、フィールドドロップダウンのオプションに表示する方法を示しています。

私たちのチャートコンポーネントは、ReactChartsで表示されるChart.jsが提供する多軸機能を利用しています。 ユーザーがデータセットとグラフの種類(線または棒)を追加できるように、UIを介して拡張しました。

この場合、Global Configを使用するための鍵は、各鍵が文字列|を保持することしかできないことを知ることです。 ブール値| 番号| null | GlobalConfigArray | GlobalConfigObject(グローバル構成値のリファレンスを参照)。

チャートごとに維持する次の項目があります。

  • 自動生成され、ユーザーが名前を変更できるchartTitle
  • 各アイテムが含まれるfields配列:
    • AirtableのfieldIdとしてのフィールド
    • 1行としてのchartOption | Chart.jsのドキュメントが示すようにバー
    • colorUtilsからのAirtableカラーとしての色
    • Airtableの色に関連する16コードとしての16進

これを管理するには、Global Configのキーと値を完全に設定するのではなく、このデータをオブジェクトとして文字列化するのが最も便利であることがわかりました。 以下の例(要点のglobalConfig.json)を参照してください。これには、患者ごとにレコードをフィルタリングするためのGlobal Config値と、先行入力フィルタリングコンポーネントをサポートするために使用されるいくつかの関連変数が含まれます(react-bootstrap-typeaheadに感謝)。

 { "xCharts": { "chart-1605425876029": "{\"fields\":[{\"field\":\"fldxLfpjdmYeDOhXT\",\"chartOption\":\"line\",\"color\":\"blueBright\",\"hex\":\"#2d7ff9\"},{\"field\":\"fldqwG8iFazZD5CLH\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425876288": "{\"fields\":[{\"field\":\"fldGJZIdRlq3V3cKu\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425876615": "{\"fields\":[{\"field\":\"fld1AnNcfvXm8DiNs\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"},{\"field\":\"fldryX5N6vUYWbdzy\",\"chartOption\":\"line\",\"color\":\"blueDark1\",\"hex\":\"#2750ae\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:37:56 AM\"}", "chart-1605425994036": "{\"fields\":[{\"field\":\"fld9ak8Ja6DPweMdJ\",\"chartOption\":\"line\",\"color\":\"blueLight2\",\"hex\":\"#cfdfff\"},{\"field\":\"fldxVgXdZSECMVEj6\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 2:39:54 AM\"}", "chart-1605430015978": "{\"fields\":[{\"field\":\"fldwdMJkmEGFFSqMy\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"},{\"field\":\"fldqwG8iFazZD5CLH\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"}],\"chartTitle\":\"New Chart\"}", "chart-1605430916029": "{\"fields\":[{\"field\":\"fldCuf3I2V027YAWL\",\"chartOption\":\"line\",\"color\":\"blueLight1\",\"hex\":\"#9cc7ff\"},{\"field\":\"fldBJjtRkWUTuUf60\",\"chartOption\":\"line\",\"color\":\"blueDark1\",\"hex\":\"#2750ae\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 4:01:56 AM\"}", "chart-1605431704374": "{\"fields\":[{\"field\":\"fld7oBtl3iiHNHqoJ\",\"chartOption\":\"line\",\"color\":\"blue\",\"hex\":\"#1283da\"}],\"chartTitle\":\"Grafico criado em 11/15/2020, 4:15:04 AM\"}" }, "xPatientEmail": "[email protected]", "xTypeaheadValue": "Elle Gold ([email protected])", "xSelectedValue": "[{\"label\":\"Elle Gold ([email protected])\",\"id\":\"[email protected]\",\"name\":\"Elle Gold\",\"email\":\"[email protected]\"}]" }

注:上記に含まれるすべてのデータ、および以下のアニメーションに含まれるデータは、実際の患者データではありません。

最終結果は次のとおりです。

AirtableダッシュボードUIのアニメーション表示。

Typeaheadはどうですか?

患者でフィルタリングするには、患者を選択し、この患者に基づいてレコードをフィルタリングする方法が必要でした。 このセクションでは、これがどのように達成されたかを確認します。

タイプアヘッドの場合、react-bootstrap-typeaheadは簡単な選択でした。残りのステップは、タイプアヘッドのオプションの準備、ブートストラップのスタイリングとロードのためのAirtable入力、およびメニューの他のいくつかのスタイルとの混合でした。 お気に入りのコンポーネントライブラリからAirtableアプリにコンポーネントをドロップすることは、通常のReactWeb開発ほど簡単ではありません。 ただし、すべてを期待どおりに表示するための追加の手順はわずかです。

最終結果は次のとおりです。

患者ごとのフィルター機能を紹介するアニメーションGIF。

Airtable入力をレンダリングし、すべてのスタイルの一貫性を保つために、react-bootstrap-typeaheadにはrenderInputプロップが付属しています。 コンポーネントのレンダリングを変更する方法について詳しくは、こちらをご覧ください。

ブートストラップスタイルとメニュー項目を上書きするために、Airtableから次の2つのユーティリティが使用されました。

  • loadCSSFromString
  • loadCSSFromURLAsync

typeahead実装の抜粋については、要点のfrontend.jsを参照してください。

この行は、ブートストラップをグローバルにロードするために使用されました。

 // frontend/index.js loadCSSFromURLAsync('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');

ホバーのスタイル変更の処理やリンクのスタイル変更( <a></a> )などのロジックが追加され、使い慣れたブートストラップのルックアンドフィールが得られます。 これには、先​​行入力のグローバル構成値の設定とレコードのフィルタリングの処理も含まれます。これにより、ユーザーがダッシュボードを離れたり、ページを更新したり、このダッシュボードを他のユーザーと共有したりした場合に、アプリは選択した患者をダッシュ​​ボードに保持します。アプリ。 これにより、ユーザーは、同じアプリの複数のコピーを同じAirtableダッシュボードに並べて、さまざまな患者を選択したり、さまざまなチャートでインストールしたりすることもできます。

Airtableのダッシュボードは、Baseのすべてのユーザーが利用できるため、ダッシュボードへのこれらのカスタムアプリのインストールは、ダッシュボードを同時に表示しているユーザーに関係なく、同じ患者とチャートにフィルターされます。

これまでカバーしてきたことを要約してみましょう。

  1. Airtableを使用すると、技術者以外のユーザーと技術者の両方がAirtableで共同作業を行うことができます。
  2. TypeformにはAirtableの統合が付属しており、技術者以外のユーザーがTypeformの結果をAirtableにマッピングできます。
  3. Airtable Appsは、マーケットプレイスから選択する場合でも、カスタムアプリを作成する場合でも、AirtableBaseを強化する強力な方法を提供します。
  4. 開発者は、これらのアプリで考えられるほぼすべての方法でAirtableを迅速に拡張できます。 上記の例では、設計と実装に3週間しかかかりませんでした(もちろん、既存のライブラリからの多大な支援を受けています)。
  5. #TAG#システムを使用すると、開発者がコードを変更しなくてもダッシュボードを変更できます。 これには、良いユースケースと悪いユースケースがあります。 この戦略を使用する場合は、必ず作成者の役割に権限を制限してください。
  6. Global Configを使用すると、開発者はアプリのインストール内でデータを永続化できます。 これを状態管理戦略に組み合わせて、コンポーネントのデータをシードします。
  7. 他のライブラリやプロジェクトからAirtableアプリに直接コンポーネントをドラッグアンドドロップすることを期待しないでください。 スタイルは、Airtableが提供するloadCSSFromStringおよびloadCSSFromURLAsyncを使用してロードできます。

将来を見据えた

より洗練されたミドルウェアを使用する

TypeformとAirtableを使用すると、質問の列へのマッピングを簡単かつ費用対効果の高い方法で構成できます。

ただし、大きな欠点が1つあります。Airtableにマッピングされた100を超える質問の調査があり、マッピングを変更する必要がある場合は、マッピング全体を削除してやり直す必要があります。 これは明らかに理想的ではありませんが、無料の統合のために、これに対処することができます。

他のオプションは、Zapier(または同様の)統合でTypeformとAirtableの間のデータを管理することです。その後、最初から始めることなく、任意の列への質問のマッピングを変更できます。 これには、考慮すべき独自のコストの考慮事項もあります。

うまくいけば、ここで学んだ教訓と伝達された教訓のいくつかが、Airtableでソリューションを構築しようとしている他の人たちに役立つことを願っています。

最後に、この記事で説明したファイルで要点を確認できます。