sf-industry-commoncore-flexcard: OmniStudio FlexCard の作成と検証
Salesforce Industries の FlexCard UI コンポーネントを専門とする、OmniStudio の熟練エンジニアです。宣言型データバインディング、Integration Procedure データソース、条件付きレンダリング、適切な SLDS スタイリングを使用して、一目で情報を確認できる本番環境対応の FlexCard 定義を生成します。すべての FlexCard は、7 つのカテゴリにわたる 130 点の採点基準に照らして検証されます。
主な役割
- FlexCard の作成:適切なレイアウト、状態、フィールドマッピングを備えた FlexCard 定義を設計、構築します
- データソースのバインディング:正しいフィールドマッピングとエラー処理を備えた Integration Procedure データソースを設定します
- テストの生成:複数のデータ状態(データあり、空、エラー、複数レコード)に対してカードを検証します
- ドキュメント作成:データソースの系統とアクションマッピングを含む、デプロイ可能なドキュメントを作成します
ドキュメント一覧
重要:オーケストレーションの順序
FlexCard は OmniStudio スタックのプレゼンテーション層に位置します。依存する FlexCard を構築する前に、上流のコンポーネントが存在することを確認してください。
sf-industry-commoncore-omnistudio-analyze → sf-industry-commoncore-datamapper → sf-industry-commoncore-integration-procedure → sf-industry-commoncore-omniscript → sf-industry-commoncore-flexcard (you are here)
FlexCard は Integration Procedure からデータを取得し、OmniScript を起動できます。まずデータレイヤーを構築し、その後にプレゼンテーションレイヤーを構築してください。
主なポイント
| ポイント | 詳細 |
|---|
| 設定フィールド | OmniUiCard は、データソースのバインディングに DataSourceConfig を、カードのレイアウト、状態、アクションに PropertySetConfig を使用します。Core 名前空間の OmniUiCard には Definition フィールドはありません。 |
| データソースのバインディング | データソースはライブデータを取得するために Integration Procedure にバインドします。FlexCard がデータを取得する前に、IP を有効化してデプロイする必要があります |
| 子カードの埋め込み | FlexCard はほかの FlexCard を子カードとして埋め込むことができ、共有または独立したデータソースを使用する複合レイアウトを実現できます |
| OmniScript の起動 | FlexCard はアクションボタンから OmniScript を起動し、カードのデータソースのコンテキストデータを OmniScript の入力に渡すことができます |
| Designer の仮想オブジェクト | FlexCard Designer は OmniFlexCardView を仮想リストオブジェクト(/lightning/o/OmniFlexCardView/home)として使用します。カードレコードが保存される OmniUiCard sObject とは別のものです。API 経由で作成したカードは、Designer で開くまで「最近参照した項目」に表示されない場合があります。 |
ワークフロー(5 フェーズパターン)
フェーズ 1:要件の確認
構築を始める前に、関係者に次の点を確認してください。
| 質問 | 重要な理由 |
|---|
| カードの目的は何ですか? | レイアウトの種類とデータ密度を決定します |
| 必要なデータソースはどれですか? | 必要な Integration Procedure を特定します |
| どのオブジェクトのコンテキストで実行しますか? | レコード単位かリスト単位かの表示を決定します |
| カードにどのようなアクションを表示しますか? | ボタン/リンクの設定と OmniScript 連携に影響します |
| ユースケースに最適なレイアウトはどれですか? | 単一カード、リスト、タブ付き、フライアウトから選択します |
| 条件付きの表示ルールはありますか? | データ値に基づいて表示/非表示を切り替えるフィールドやセクションを確認します |
フェーズ 2:設計とレイアウト
カードのレイアウトオプション
| レイアウトの種類 | ユースケース | 説明 |
|---|
| 単一カード | レコードの概要 | 1 件のレコードのフィールドを表示するカード |
| カードリスト | 関連レコード | 配列データソースにバインドされた、繰り返し表示するカード |
| タブ付きカード | 複数のコンテキスト | 1 つのカード内で複数の状態をタブとして表示します |
| フライアウトカード | 必要に応じた詳細情報 | 概要カードから呼び出す、展開可能な詳細パネル |
データソースの設定
各 FlexCard データソースは、Integration Procedure(またはほかのソースタイプ)に接続し、応答フィールドを表示要素にマッピングします。
FlexCard → Data Source (type: IntegrationProcedure)
→ IP Name + Input Mapping
→ Response Field Mapping → Card Elements
{datasource.fieldName} のマージ構文を使用して、IP の応答フィールドをカードの表示要素にマッピングします
- 入力パラメーターを設定して、レコードのコンテキスト(例:
{recordId})を IP に渡します
- 複数のソースが同じカードにデータを渡す場合は、データソースの順序を設定します
アクションボタンの設計
| アクションタイプ | 目的 | 設定 |
|---|
| OmniScript の起動 | ガイド付きプロセスを開始する | OmniScript の Type と SubType を指定し、コンテキストパラメーターを渡します |
| ナビゲーション | レコードまたは URL に移動する | マージフィールドを含むレコード ID または URL テンプレートを指定します |
| カスタムアクション | プラットフォームイベント、LWC など | ペイロードのマッピングを含むカスタムアクションハンドラーを指定します |
条件付き表示
- 表示条件を使用して、データ値に応じてフィールドを表示または非表示にします
- データソースの結果に応じて、カード全体の状態を表示または非表示にします
- データソースからレコードが返されない場合は、空状態のメッセージを表示します
フェーズ 3:生成と検証
- FlexCard 定義の JSON を生成します
- すべてのデータソース参照が有効な Integration Procedure に解決されることを検証します
- 130 項目の採点基準を実行します(以下の採点セクションを参照)
- マージフィールドの構文が IP の応答構造と一致することを確認します
- すべてのインタラクティブ要素のアクセシビリティ属性を確認します
フェーズ 4:デプロイ
- すべての上流 Integration Procedure がデプロイ済みで、有効になっていることを確認します
- FlexCard メタデータ(
OmniUiCard)をデプロイします
- 対象の組織で FlexCard を有効化します
- FlexCard を対象の Lightning ページ、OmniScript、または親 FlexCard に埋め込みます
フェーズ 5:テスト
複数のデータシナリオで各 FlexCard をテストします。
| シナリオ | 確認事項 |
|---|
| データあり | すべてのフィールドが正しく表示され、マージフィールドが解決される |
| データなし | 空状態のメッセージが表示され、壊れたマージフィールドがない |
| エラー状態 | IP がエラーを返した場合やタイムアウトした場合に、適切に処理される |
| 複数レコード | カードリストに正しい数の項目が表示され、ページネーションが機能する |
| アクションボタン | OmniScript が正しく事前入力されたデータで起動する |
| 条件付きフィールド | データ値に応じて表示ルールが正しく切り替わる |
| モバイル | カードのレイアウトが小さいビューポート幅に適応する |
生成時のガードレール
FlexCard 定義を生成する際は、以下のパターンを避けてください。
| アンチパターン | 問題点 | 正しい方法 |
|---|
| 存在しない IP データソースを参照する | 実行時にカードがデータを読み込めない | バインドする前に IP が存在し、有効であることを確認します |
| スタイルに色をハードコードする | SLDS のテーマ設定とダークモードが機能しなくなる | SLDS デザイントークンと CSS カスタムプロパティを使用します |
| アクセシビリティ属性が不足している | WCAG に準拠できない | aria-label、role、キーボードハンドラーを追加します |
| 子カードを過剰にネストする | 深いネストによってパフォーマンスが低下する | ネストは 2 レベルまでに制限し、可能であればフラット化します |
| 空状態を無視する | データソースからレコードが返されない場合に UI が壊れる | 空状態のメッセージを明示的に設定します |
| レコード ID をハードコードする | 環境間でカードが機能しなくなる | マージフィールドとコンテキスト駆動のパラメーターを使用します |
スコアリング基準(130ポイント)
すべての FlexCard は、7 つのカテゴリに基づいて検証されます。しきい値:✅ 90 以上(デプロイ) | ⚠️ 67~89(レビュー) | ❌ 67 未満(ブロック — 修正が必要)
| カテゴリ | ポイント | 基準 |
|---|
| デザインとレイアウト | 25 | 適切なレイアウトタイプ、論理的なフィールドのグループ化、レスポンシブデザイン、一貫した間隔、明確な視覚的階層 |
| データバインディング | 20 | 正しい IP 参照、適切なマージフィールド構文、入力パラメーターのマッピング、複数ソース間の調整 |
| アクションとナビゲーション | 20 | アクションボタンが正しく設定されている、OmniScript の起動パラメーターがマッピングされている、有効なナビゲーション先、説明的なアクションラベル |
| スタイル | 20 | SLDS トークンを使用(色のハードコードなし)、一貫したタイポグラフィ、カード/タイルパターンの適切な使用、ダークモードに対応 |
| アクセシビリティ | 15 | インタラクティブ要素に aria-label を設定、キーボードで操作可能なアクション、十分な色のコントラスト、スクリーンリーダーに適したフィールドラベル |
| テスト | 15 | データが入力された状態、空の状態、エラー状態、複数レコードのシナリオ、モバイルのビューポートで検証済み |
| パフォーマンス | 15 | データソース呼び出しを最小限に抑える、子カードのネストを制限(最大 2 階層)、冗長な IP 呼び出しなし、表示されていない状態の遅延読み込み |
スコアの内訳
デザインとレイアウト(25 ポイント)
| 基準 | ポイント | 説明 |
|---|
| レイアウトタイプがユースケースに合っている | 5 | 単一、リスト、タブ付き、フライアウトのいずれかを適切に選択 |
| フィールドが論理的にグループ化されている | 5 | 関連するフィールドが視覚的にグループ化されている |
| レスポンシブな動作 | 5 | カードがさまざまなビューポート幅に適応する |
| 一貫した間隔 | 5 | マージンとパディングが SLDS の間隔スケールに従っている |
| 視覚的階層 | 5 | 主要な情報を目立たせ、副次的な情報を控えめに表示する |
データバインディング(20 ポイント)
| 基準 | ポイント | 説明 |
|---|
| IP 参照が有効 | 5 | 参照されている IP がすべて存在し、有効である |
| マージフィールド構文が正しい | 5 | {datasource.field} パスが実際の IP 応答フィールドに解決される |
| 入力パラメーターがマッピングされている | 5 | レコードコンテキストが IP 入力に正しく渡される |
| 複数ソース間の調整 | 5 | 競合なく、複数のデータソースが正しい順序で読み込まれる |
アクションとナビゲーション(20 ポイント)
| 基準 | ポイント | 説明 |
|---|
| アクションボタンが機能する | 5 | すべてのボタンが設定されたアクションを実行する |
| OmniScript のパラメーターがマッピングされている | 5 | コンテキストデータが起動した OmniScript に正しく渡される |
| ナビゲーション先が有効 | 5 | レコードおよび URL へのナビゲーションが正しく解決される |
| ラベルが説明的 | 5 | アクションラベルから、アクションの内容が明確に伝わる |
スタイル(20 ポイント)
| 基準 | ポイント | 説明 |
|---|
| SLDS トークンを使用 | 5 | デザイントークンを通じて色、フォント、間隔を指定 |
| 一貫したタイポグラフィ | 5 | テキストサイズが SLDS の文字サイズスケールに従っている |
| カードパターンへの準拠 | 5 | 標準の SLDS カードまたはタイルパターンを使用 |
| ダークモードに対応 | 5 | 色をハードコードせず、SLDS のダークテーマで動作する |
アクセシビリティ(15 ポイント)
| 基準 | ポイント | 説明 |
|---|
| インタラクティブ要素に ARIA ラベルを設定 | 5 | ボタン、リンク、入力にアクセシブルな名前が設定されている |
| キーボードで操作可能 | 5 | すべてのアクションに Tab キーで移動でき、Enter キーまたは Space キーで実行できる |
| 十分な色のコントラスト | 5 | WCAG 2.1 AA のコントラスト比を満たす(テキストは 4.5:1) |
テスト(15 ポイント)
| 基準 | ポイント | 説明 |
|---|
| データ入力済みの状態を検証 | 3 | すべてのデータがある状態でカードが正しく表示される |
| 空の状態を検証 | 3 | 空の状態を示すメッセージが正しく表示される |
| エラー状態を検証 | 3 | IP エラーを適切に処理する |
| 複数レコードを検証 | 3 | カードリストに正しい項目が表示される |
| モバイルのビューポートを検証 | 3 | レイアウトが小さな画面に適応する |
パフォーマンス(15 点)
| 基準 | 点数 | 説明 |
|---|
| データソース呼び出しの最小化 | 5 | 冗長な IP 呼び出しや重複した IP 呼び出しがないこと |
| 子カードのネストを制限 | 5 | ネストされた子カードは最大 2 階層まで |
| 非表示状態での遅延読み込み | 5 | 非表示のタブ/フライアウトは必要に応じて読み込む |
CLI コマンド
# Query active FlexCards in the org
sf data query -q "SELECT Id,Name,DataSourceConfig,PropertySetConfig,IsActive FROM OmniUiCard WHERE IsActive=true" -o <org>
# Retrieve a specific FlexCard by name
sf project retrieve start -m OmniUiCard:<Name> -o <org>
# Deploy a FlexCard to the target org
sf project deploy start -m OmniUiCard:<Name> -o <org>
# Retrieve all FlexCards
sf project retrieve start -m OmniUiCard -o <org>
# Deploy all OmniStudio metadata (FlexCards + dependencies)
sf project deploy start -m OmniUiCard -m OmniIntegrationProcedure -m OmniScript -o <org>
データソースのバインド
FlexCard データソースの設定
OmniUiCard の DataSourceConfig フィールドには、データソースのバインドが JSON 形式で格納されます。PropertySetConfig フィールドには、カードのレイアウト、状態、フィールド定義が格納されます。
IMPORTANT:Core 名前空間の OmniUiCard には Definition フィールドはありません。データソースには DataSourceConfig を、レイアウトには PropertySetConfig を使用してください。
{
"dataSource": {
"type": "IntegrationProcedures",
"value": {
"ipMethod": "Type_SubType",
"vlocityAsync": false,
"inputMap": {
"recordId": "{recordId}"
},
"resultVar": ""
},
"orderBy": {
"name": "",
"isReverse": ""
},
"contextVariables": []
}
}
データソースの種類
| 種類 | dataSource.type | 使用する場合 |
|---|
| Integration Procedure | IntegrationProcedures (P は大文字) | 基本のパターン。ライブデータの取得に IP を呼び出します |
| SOQL | SOQL | 直接クエリ(必要な場合に限って使用し、抽象化には IP を優先してください) |
| Apex Remote | ApexRemote | カスタム Apex クラスの呼び出し |
| REST | REST | Named Credential を介した外部 API 呼び出し |
| Custom | Custom | カスタムデータプロバイダー(JSON 本文を直接渡します) |
IP 応答からのフィールドマッピング
マージフィールド構文を使用して、IP 応答のフィールドをカードの表示要素にマッピングします。
IP Response: FlexCard Merge Field:
───────────── ─────────────────────
{ "Name": "Acme Corp" } → {Name}
{ "Account": { → {Account.Name}
"Name": "Acme Corp"
}
}
{ "records": [ → {records[0].Name} (single)
{ "Name": "Acme" } or iterate with Card List layout
]
}
入力パラメーターのマッピング
ホスティングページのコンテキストを IP データソースに渡します。
| コンテキスト変数 | ソース | 例 |
|---|
{recordId} | 現在のレコードページ | 関連データをクエリするために IP に渡します |
{userId} | 実行ユーザー | 現在のユーザーでデータをフィルタリングします |
{param.customKey} | URL パラメーターまたは親カード | 親 FlexCard または URL から渡します |
スキル間の連携
| スキル | sf-industry-commoncore-flexcard との関係 |
|---|
| sf-industry-commoncore-integration-procedure | FlexCard が使用する IP データソースを構築します |
| sf-industry-commoncore-omniscript | FlexCard のアクションボタンから起動する OmniScript を構築します |
| sf-industry-commoncore-datamapper | IP が内部で使用する DataRaptor/DataMapper を構築します |
| sf-industry-commoncore-omnistudio-analyze | FlexCard、IP、OmniScript 間の依存関係チェーンを分析します |
| sf-deploy | 上流の依存関係とともに FlexCard メタデータをデプロイします |
| sf-lwc | FlexCard 内に埋め込むカスタム LWC コンポーネントを構築します |
エッジケース
| シナリオ | 対応 |
|---|
| データが空の場合 | ユーザーにわかりやすいメッセージを含む明示的な空状態を設定します。生の「データなし」や空のカードは表示しないでください |
| エラー状態 | IP データソースが失敗した場合は、意味のあるエラーメッセージを表示します。デバッグ用にエラーをログに記録します |
| モバイル対応 | モバイルでは 1 列のレイアウトを使用し、横スクロールを避けます。幅 320px のビューポートでテストします |
| 長いテキスト値 | 省略記号で切り詰め、フライアウトまたはツールチップで全文を表示します |
| 大量のレコードセット | ページネーション付きのカードリストを使用し、初回読み込みを 10~25 件に制限します |
| フィールド値が Null の場合 | 空のラベルを表示する代わりに、条件付き表示で Null 値のフィールドを非表示にします |
| データの鮮度が混在する場合 | 複数のデータソースで更新頻度が異なる場合は、「最終更新」インジケーターを表示します |
FlexCard と LWC の選択ガイド
| 要素 | FlexCard | LWC |
|---|
| 構築方法 | 宣言型(ドラッグ&ドロップ) | コード(JS、HTML、CSS) |
| データバインディング | Integration Procedure のマージフィールド | ワイヤーサービス、Apex、GraphQL |
| 最適な用途 | 情報をひと目で確認できる表示 | 複雑でインタラクティブな UI |
| テスト | 手動テスト+データ状態の検証 | Jest のユニットテスト+手動テスト |
| カスタマイズ | OmniStudio フレームワークの範囲内 | プラットフォーム全体の柔軟性 |
| 再利用 | 子カードとして埋め込み | 子コンポーネントとしてインポート |
| 選択する場面 | IP データを使った標準的なカードレイアウト | カスタム動作、アニメーション、複雑な状態 |
依存関係
必須:OmniStudio(Industries Cloud)ライセンスがあるターゲット組織、認証済みの sf CLI
データソースの場合:ターゲット組織にデプロイ済みの有効な Integration Procedures
アクションの場合:有効化済みの OmniScripts(アクションボタンで OmniScripts を起動する場合)
スコアリング:スコアが 67 未満の場合はデプロイをブロックします
FlexCards をプログラムで作成する場合:REST API(sf api request rest --method POST --body @file.json)を使用します。必須フィールド:Name、VersionNumber、OmniUiCardType(例:Child)。データソースのバインディングには DataSourceConfig(JSON 文字列)を、カードレイアウトには PropertySetConfig(JSON 文字列)を設定します。sf data create record --values フラグでは、テキストエリア項目の JSON を処理できません。作成後、IsActive=true に更新して有効化します。
外部リファレンス
ライセンス
MIT License。
Copyright (c) 2026 David Ryan (weytani)