ダッシュボード
ダッシュボードの標準機能ではカバーしきれない制御を、サーバースクリプトと CSS で補う方法をまとめます。
- タイムラインは基準サイトの
view.Filtersが全サイトに適用される。サイト ID を条件に含めた OR フィルタを基準サイトに書けば、サイトごとに条件を変えられる - 一覧パーツは、一覧側のサイトの「ビュー処理時」サーバースクリプトで
context.Id(ダッシュボードのサイト ID)を判定してviewを設定する - カスタム HTML パーツに埋め込んだ Metabase の iframe は、CSS で高さを補えばパーツのサイズに追従する

ダッシュボード経由のアクセスを判別する
ダッシュボードからデータが取得されたとき、サーバースクリプトの context には次の値がセットされます。
| プロパティ | 値 |
|---|---|
context.Controller | items |
context.Action | dashboardpart |
context.Id | ダッシュボードのサイト ID |
タイムラインでサイトごとにフィルタを設定する
課題
1 つのタイムラインパーツに複数のサイトを設定した場合、ダッシュボードの管理画面で設定したフィルタは全サイトに一律で適用されます。また、各サイトのサーバースクリプトで view.Filters を設定していても、基準サイトに設定したものが他のサイトにも適用され、他のサイトのフィルタは無視されます。
解決方法
基準サイトの view.Filters が全サイトに適用されることを逆手に取り、基準サイトのサーバースクリプトに全サイト分の条件をまとめて書きます。フィルタの OR / AND 機能を使い、サイト ID を条件に含めます。
例として、サイト ID 100(基準サイト)では状況が 100(既定では「未着手」)、サイト ID 200 では状況が 900(既定では「完了」)のレコードを表示します。つまり「(サイト ID 100 かつ 状況 100)または(サイト ID 200 かつ 状況 900)」という条件です。
if (context.Action === 'dashboardpart') {
let data = {};
data.and_Filter1 = JSON.stringify({
SiteId: 100,
Status: '[100]'
});
data.and_Filter2 = JSON.stringify({
SiteId: 200,
Status: '[900]'
});
view.Filters.or_Filter = JSON.stringify(data);
}キーが or_ で始まるフィルタは中身の条件を OR で、and_ で始まるフィルタは中身の条件を AND でまとめます(1.5.8.1 の View.cs)。上の例は or_Filter の中に and_Filter1 と and_Filter2 を入れているので、「(サイト ID 100 かつ 状況 100)または(サイト ID 200 かつ 状況 900)」になります。
context.Action が dashboardpart のときだけ実行するようにして、一覧表示などダッシュボード以外の画面でこのフィルタが効かないようにしています。
一覧パーツにフィルタ・ソータを適用する
一覧パーツには、「既定のビュー」が設定されていればそれが、なければ更新日時の降順がソートキーとして適用されます。これ以外のフィルタやソータを使いたい場合は、サーバースクリプトの view を使います。view は API や画面表示など、どの経路でデータを取得しても適用されます。
- 設定先: 一覧として表示するサイト
- 条件: ビュー処理時
if (context.Id == 3659528) /*ダッシュボードのサイトID*/ {
view.ClearFilters();
switch (context.UserId) {
case 3:
view.Filters.ClassA = '["野菜"]'
break;
case 7:
view.Filters.ClassA = '["フルーツ"]'
break;
default:
break;
}
}context.Idでダッシュボードのサイト ID を判定し、ダッシュボード経由のときだけviewを適用しています。view.ClearFilters()でフィルタをリセットし、「既定のビュー」の影響を取り除いています。
view の詳しい使い方は公式マニュアルの サーバスクリプト:view.Filters を参照してください。
同じサイトの一覧を複数配置する場合は使えない
アクセス元の判別はダッシュボードのサイト ID でしか行えないため、1 つのダッシュボードに同じサイトの一覧パーツを複数配置すると、すべてに同じ view が適用されます。パーツごとに分けるにはダッシュボードパーツの ID(dashboardPartId)が必要ですが、確認したソースでもサーバースクリプトの context にこの値を渡すプロパティはありません(ServerScriptModelContext.cs)。
Metabase の埋め込みをパーツのサイズに追従させる
カスタム HTML パーツに Metabase の埋め込みコードを貼ると、iframe に指定された固定サイズ(例: width="800" height="600")のまま表示され、パーツやウインドウのサイズを変えても追従しません。サイズ指定を外すと最小サイズになり、iframe に width: 100%; height: 100%; を指定しても、横幅は広がりますが高さは広がりません。
原因
カスタム HTML は .grid-stack-item > .grid-stack-item-content > #DashboardPart_1 > .dashboard-custom-html-body の中に配置されます。このうち .grid-stack-item-content には次の CSS が設定されており、position: absolute のため高さが失われています。
.grid-stack>.grid-stack-item>.grid-stack-item-content {
margin: 0;
position: absolute;
width: auto;
overflow-x: hidden;
overflow-y: auto;
}対処
Metabase の埋め込みコードからサイズ指定を外し、識別用のクラスを付けます。すべての iframe に適用されないようにするためです。
diff<iframe src="https://*****/public/question/e05274f1-3388-4211-8586-8a0ce21be55b" frameborder="0" - width="800" - height="600" + class="metabase_iframe" allowtransparency ></iframe>高さを補う CSS を、ダッシュボードのサイトの管理で、スタイルに追加します。すべてのダッシュボードに適用する場合は拡張スタイルに設定します。
css:has(.metabase_iframe) { .grid-stack > .grid-stack-item > .grid-stack-item-content { height: calc(100% - 20px); div[id^=DashboardPart] { height: 100%; .dashboard-custom-html-body { height: 100%; iframe { height: 100%; width: 100%; } } } } }
これでパーツのサイズ変更に追従します。Metabase の iframe 上のイベントと一部競合するため、ポインタの動きに引っかかりが出ることがあります。Metabase 以外の iframe にも同じ方法が使えます。