🌊

【Flow Builder x LWC】Custom Property Editor 試してみた

2021/04/06に公開

SalesforceのFlow Builderのエディター設定定義部分をLWCで構築できる Custom Property Editor LWCを試してみました。
検証時のAPIバージョンは51です。常に最新の情報を公式ドキュメントで確認するようお願いします。

百聞は一見に如かず。以下のようなもの作ることができました。

Flow Builder
Flow Builder画面

Flow実行時
Flow 実行画面

Flow Builder内でHTML Canvasを表示し、お絵かきができるようにしています。これが Custom Property Editor です。描いたデータをbase64化して、Flowで表示するLWCに入力値として渡しています。
そして実行時に、Builderで定義された画像データを、Flow Screen Component (LWC)で表示しています。
ソースコードはこちら
※サンプルコードです。

Custom Property Editorについて

Flow Builder内で、設定定義のUIを自由に構築できる機能です。
標準ではシンプルなテキスト入力しかできなかったのをより柔軟に設定できるようにするのが目的で、UIはLightning Web Componentで構築します。
この機能はWinter '21でGAとなりました。公式ドキュメント

Custom Property Editorを使用可能な領域は以下の2つです。

  • Flow Action (Apex @InvocableMethod)
  • Flow Screen Component(LWC)

Flow Action (Apex @InvocableMethod)への指定方法

公式ドキュメント(サンプル)

MyAction.apex
global class MyFlowAction {

  @InvocableMethod(label='My Action Name' configurationEditor='c-my-custom-property-editor-for-action')
  global static List<MyResult> execMyAction(List<MyRequest> requests) {
    ...
  }

@InvocableMethodの configurationEditor に c- をつけてCustom Property EditorのLWC名を、ケバブケースで指定(カスタム名前空間がある場合はc-の箇所を変更)します。
これでFlow Builderでアクションを配置すると、Custom Property Editorが表示されます。

CustomPropertyEditorForAction.js
import { LightningElement, api } from 'lwc';
export default class CustomPropertyEditorForAction extends LightningElement {
  // 入力変数
  @api
  inputVariables;
  /* データ構造は以下のよう
  [{
    name: 'variableApiName', // 変数API名
    value: '値',
    valueDataType: 'String' // データ型
  }]
  */
  
  // validate()で、Flow Builder上で、設定入力のバリデーションルールを定義。
  // カスタムのエラーメッセージをArrayで返す。
  @api
  validate() {
    const validity = [];
    // ここでEditorの入力値バリデーションロジックを記述
    if (false) {
      validity.push({
        key: 'UniqueErrorKey',
        errorString: 'エラーメッセージ',
      });
    }
    return validity;
  }
  
  notifyValueChangeToFlowBuilder() {
    // 'configuration_editor_input_value_changed' というカスタムイベントをDispatchで、
    // Flow Builderの設定値を更新する
    const valueChangedEvent = new CustomEvent(
      'configuration_editor_input_value_changed',
      {
	bubbles: true,
	cancelable: false,
	composed: true,
	detail: {
	  name,
	  newValue,
	  newValueDataType: 'String',
	}
      }
    );
    this.dispatchEvent(valueChangedEvent);
  }
}

いくつかCustom Property Editor用のJavaScript Interfaceが登場します。

  • @api inputVariables; : 入力変数が格納されている。
  • @api validate() : 入力バリデーション。返り値のarrayのlength > 0の場合、エラー扱い。

また、公式ドキュメントではまとめられていませんが、CustomEventを使ってEditorの変更を通知します。

  • configuration_editor_input_value_changed CustomEvent : 変更をビルダーに反映
CustomPropertyEditorForAction.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>false</isExposed>
</LightningComponentBundle>

isExposedはtrueでもfalseでもよいようです。

この他に未検証ですが、ジェネリック型sObjectに対応したサンプルも公式ドキュメントで確認できます。

inputVariablesの他に、builderContextgenericTypeMappings インターフェースプロパティが加わります。genericTypeMappingsでは、Apexの@InvocableVariableで定義したプロパティの型情報が、入力なら T__、出力ならU__のプリフィックス付きでプロパティごとに格納されています。

そしてsObjectの種類(Accont, Caseなど)の変更時には configuration_editor_generic_type_mapping_changed Custom Eventをディスパッチし、sObjectのレコードの変更時には、configuration_editor_input_value_changed をディスパッチし更新を通知と、2種類のCustom Eventを駆使する必要があるようです。


Flow Screen Component(LWC)への指定方法

基本的に Flow Actionと同様です。
今回作成したHTML CanvasのCustom Property Editorはこちらを使いました。

Flow Screen Component
lwcForFlowWithCustomPropertyEditor.html
<template>
    <h1>LWC for Flow with Custom Property Editor</h1>
    <p>Flow Builder上で描いたサインです↓</p>
    <div>
      <img src={base64image} />
    </div>
</template>
lwcForFlowWithCustomPropertyEditor.js
import { LightningElement, api  } from "lwc";
export default class LwcForFlowWithCustomPropertyEditor extends LightningElement {
  @api
  base64image;
}

Flow Screen Componentでは、Apexの@InvocableVariableの代わりに、@apiとして定義します。

lwcForFlowWithCustomPropertyEditor.js-meta.xml
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
  <apiVersion>51.0</apiVersion>
  <isExposed>true</isExposed>
  <masterLabel
  >Canvasを使ったCustom Property Editorが定義されたFlow Screen Component</masterLabel>
  <targets>
    <target>lightning__FlowScreen</target>
  </targets>
  <targetConfigs>
    <targetConfig
      targets="lightning__FlowScreen"
      configurationEditor="c-custom-canvas-property-editor"
    >
      <property name="base64image" type="String" />
    </targetConfig>
  </targetConfigs>
</LightningComponentBundle>

lightning__FlowScreen ターゲットのtargetConfigの configurationEditor 属性に、Custom Property EditorのLWC名を名前空間 + ケバブケースで追加。さらに入力で使う変数をpropertyに指定します。
1つのLWCのスクリーンコンポーネントにつき、1つのCustom Property Editorしか使用できません。
CustomEventで複数のpropertyの値を変更していきます。

Custom Property Editor
customCanvasPropertyEditor.html
<template>
  <h1>HTML Canvas in Flow Builder (Custom Property Editor)</h1>
  <canvas class="canvas" id="canvas" width="240" height="180"></canvas>
  <lightning-button
    label="Clear"
    variant="brand"
    onclick={onClickClear}
  ></lightning-button>
</template>
customCanvasPropertyEditor.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>true</isExposed>
	<masterLabel>HTML Canvas Editor</masterLabel>
</LightningComponentBundle>
customCanvasPropertyEditor.js
import { LightningElement, api } from 'lwc';

export default class CustomCanvasPropertyEditor extends LightningElement {
  // ...
  // getter / setterに分けています。
  _inputVariables = [];

  @api
  get inputVariables() {
    return this._inputVariables;
  }

  set inputVariables(variables) {
    // 入力変数に対応して、CanvasにBase64の画像を反映
    const param = variables.find(({ name }) => name === "base64image");
    if (param) {
      // ...保存された入力値(画像データ)をCanvasに表示
    }
    this._inputVariables = variables || [];
  }

  // ...描画処理

  // Flow Builderに、描いたものをBase64化して文字列で渡す。
  submit = () => {
    const base64 = this.canvas.toDataURL("image/jpeg");
    const valueChangedEvent = new CustomEvent(
      "configuration_editor_input_value_changed",
      {
        bubbles: true,
        cancelable: false,
        composed: true,
        detail: {
          name: "base64image",
          newValue: base64,
          newValueDataType: "String"
        }
      }
    );
    this.dispatchEvent(valueChangedEvent);
  };
}

Flow Actionで使った configuration_editor_input_value_changed をこちらでも使用して、Custom Property Editorの設定値をビルダーに通知します。

Screen Componentでも、ジェネリック型sObjectをサポートしているようです。


以上、まだ情報が少ない領域だったので、まとめてみました。

SalesforceのLightning Flowはノーコードツールとしてどんどん進化し非常に強力ですが、複雑な処理や、動的な入力・出力など細かいところに手が届かないケースがあります。しかしそれを補完する役割としてLWCのFlow Screen Components, Apexの@Invocable Method、さらにこの Custom Property Editor が加わり、Flowがより一層柔軟かつ強力になったと感じます。

Discussion