とあるSalesforce親方の日記

ちょっと長いことSalesforce開発やってます。

LWCの話題にかこつけて、すっかり忘れてたアイツ(Aura component)の話をする

※この記事はSalesforce 開発者向けブログ投稿キャンペーンへのエントリー記事です。

 

皆様こんにちは。親方です。

みんな、LWC書いてますかー!!!?

ぼくは、Visualforce書いてまーす!

だってClassicサポートしないといけないんだもん

去る6/25にTrailheaDX2020が開催されましたね!

午前0時過ぎから約6時間のナイトパーティーとはなんと粋なスケジュールだったことか(彼らは朝~昼の感覚です)

けど6/28現在、メンテで録画コンテンツが見れん!!!!?

これでは記事が書けん・・・

 

・・・てなわけで、あんま関係ないこと書きます。

Auraコンポーネントのこと、覚えてますか?

Lightning ExperienceのDev向け目玉コンテンツであったLightningコンポーネント、そのプログラミング基盤として「Aura」が採用されておりました。

これが主流になるから、という触れ込みだったのと上級Dev資格取得に必要だったのでTrailheadでコツコツ勉強しました。その頃にLEX開発やってた案件ではこれ使ったコンポーネントも作りましたよ。

今でもオープンソースだよ!停止してるけど

リファレンスはこちら

Lightning Aura コンポーネント開発者ガイド

そして2018年、Auraはおわりました。

Lightning Web Component(LWC)の登場によって、Auraはレガシーとなり、基盤のリポジトリも止まり、成長が止まりました。

けれども完全に息の根が止まったわけではありません。

コンポーネントライブラリには今でもAura向けのコンポーネントの掲載がありますし、跡形もなく消えたSコンと違って最新環境でもビルドできます。

 まだだ、まだ終わらんよ!

今回の記事は、そんな中途半端な時期にLightningコンポーネントを修得・実装していたAuraバトラー達の鎮魂のためになればと思い記述したものです。

昔こんなの作ってた

去年のLightning Championの活動の一環として、なんかサンプルコード書かねば・・・という危機感から作ったコードがあります。

カスタムJavascriptボタンがClassicでしか使えないため、Lightning Experience環境で代替できるものを作った感じです。

Aura1:①Contact新規作成アクション(<force:recordData>を使った初期値登録)

Aura2:②Account・Contact一括コピーアクション(Apexコントローラで一括取得・登録)

 

画面

<aura:component implements="force:hasRecordId,force:lightningQuickAction" access="global" >
    <aura:handler name="render" value="this" action="{!c.doInit}"/>
    <aura:attribute name="rec" type="Object"/>
    <aura:attribute name="recordInfo" type="Object"/>
    <aura:attribute name="recordId" type="String" />
    <aura:attribute name="recordLoadError" type="String"/>
    
    <!-- 起動時にレコード情報を読み込み -->
    <force:recordData aura:id="recordLoader"
        recordId="{!v.recordId}"
        fields="Name,Phone,Description,BillingCity,BillingStreet,BillingState,BillingPostalCode,BillingCountry"
        targetFields="{!v.rec}"
        targetError="{!v.recordLoadError}"
    />

</aura:component>

コントローラ

({
    //新規作成画面を呼び出し、force:recordDataで受信したレコード情報を初期値として差し込んで表示
    doInit : function(component, event, helper) {
        
        var createRecordEvent = $A.get("e.force:createRecord");
        
        /* 新規作成画面にパラメータを設定
         * entityApiName:対象オブジェクト
         * defaultFieldValues:初期値を差し込む項目
        */
        createRecordEvent.setParams({
            "entityApiName": "Contact",
            "defaultFieldValues":{
                "Phone":component.get("v.rec.Phone"),
                "Email":"test@testcompany.co.jp",
                "Description":component.get("v.rec.Description"),
                "MailingStreet":component.get("v.rec.BillingStreet"),
                "MailingCity":component.get("v.rec.BillingCity"),
                "MailingState":component.get("v.rec.BillingState"),
                "MailingPostalCode":component.get("v.rec.BillingPostalCode"),
                "MailingCountry":component.get("v.rec.BillingCountry"),
                "AccountId":component.get("v.recordId")
            }
        });
        
        //新規作成画面を表示
        createRecordEvent.fire();
        }
})

これをLWCで書くと

ちょうど良いサンプルコードとして、これをLWCに移植することを試みました。

以下の点に気をつけながら移植していきます。

 

画面

<template>
    <!-- 起動時にレコード情報を読み込み -->
    <div class="slds-p-top_large">
        <lightning-record-edit-form object-api-name={objectApiName}>
            <lightning-messages>
            </lightning-messages>
            <lightning-input-field field-name="AccountId">
            </lightning-input-field>
            <lightning-input-field field-name="Name">
            </lightning-input-field>
            <lightning-input-field field-name="Phone">
            </lightning-input-field>
            <lightning-input-field field-name="Description">
            </lightning-input-field>
            <lightning-input-field field-name="MailingStreet">
            </lightning-input-field>
            <lightning-input-field field-name="MailingCity">
            </lightning-input-field>
            <lightning-input-field field-name="MailingState">
            </lightning-input-field>
            <lightning-input-field field-name="MailingPostalCode">
            </lightning-input-field>
            <lightning-input-field field-name="MailingCountry">
            </lightning-input-field>
                <lightning-button
                    class="slds-m-top_small"
                    type="submit"
                    label="新規作成">
                </lightning-button>
        </lightning-record-edit-form>
    </div>
</template>

コントローラ

import { LightningElement, api, wire  } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import CONTACT_OBJECT from '@salesforce/schema/Contact';

const FIELDS = [
    'Account.Id',
    'Account.Name',
    'Account.Phone',
    'Account.Description',
    'Account.BillingCity',
    'Account.BillingStreet',
    'Account.BillingState',
    'Account.BillingPostalCode',
    'Account.BillingCountry',     
];

export default class LwcComp1 extends LightningElement {
    @api recordId;
    objectApiName = CONTACT_OBJECT;
    @wire(getRecord, { recordId: '$recordId', fields: FIELDS })
    wiredRecord({ error, data }) {
        if (data) {
            console.log('success');
            console.log(data);
            
            this.AccountId = getFieldValue(data, 'Account.Id');
            this.Phone = getFieldValue(data, 'Account.Phone');
            this.Description = getFieldValue(data, 'Account.Description');
            this.MailingStreet = getFieldValue(data, 'Account.BillingStreet');
            this.MailingCity = getFieldValue(data, 'Account.BillingCity');
            this.MailingState = getFieldValue(data, 'Account.BillingState');
            this.MailingPostalCode = getFieldValue(data, 'Account.BillingPostalCode');
            this.MailingCountry = getFieldValue(data, 'Account.BillingCountry');
            
        } else if (error) {
            // Handle error. Details in error.message.
            console.log('error');
            console.log(error);
        }
    }

}

基本方針はわかった。しかし・・・

基本的に、AuraでできることはだいたいLWCでできます。

しかし、現行LWCの仕様ではできないことがあります。

Lightningレコードページから呼び出すアクションに指定できないんです。

今見たらやっぱりAuraで作ることになってました

これ今でもできないんでしたっけ・・・?

Lightning アクションは、既存の Lightning コンポーネントフレームワーク上に構築されます。既存の Aura コンポーネントを簡単にアクションに変換して、Salesforce モバイルアプリケーションや Lightning Experience で使用することができます。

Aura コンポーネントをアクションとして起動可能にするために、force:lightningQuickAction と force:lightningQuickActionWithoutHeader のいずれかのインターフェースをコンポーネントに追加します。

上述したforce:recordDataと同様に、force:XXXインターフェースはLWCには存在しないんです。

LWC時代にはどうやって作ればよいのでしょうか。

色々考えてみた

Auraコンポーネントの中にLWCを入れる

実は、AuraコンポーネントとLWCは入れ子構造にすることができます。

(常にAura側が親となる)

Lightning Web コンポーネントからの Aura コンポーネントの作成

一旦LWCを作った後、外枠としてAuraコンポーネントを作成し、そこにLWCを差し込むことでほぼLWCなAuraコンポーネントを作成することができます。

<aura:component implements="force:hasRecordId,force:lightningQuickAction">
    <c:lwcActionDetail name="LWC" />
</aura:component>
  • メリット:ほぼLWCで作れる
  • デメリット:形式上Auraは残る
Lightningフローを使う

Lightningコンポーネントと同様に、画面フローもまたアクションから呼び出すことができます。

(グローバルアクションを除く)

フローをうまく使えば数百件クラスの一括データ操作も可能ですし、いっそノンコーディングに置き換えるのも選択肢かと思います。

またTrailheaDXネタですが、Javascrpitを動かしたいのであれば"Salesforce Functions"も選択肢に含まれます。Salesforce Functionsはフローの中からサーバサイド処理として呼び出せるため、Lightningコンポーネントのコントローラを移植することができるのではないのでしょうか。

  • メリット:ノンコーディング開発できる
  • デメリット:UIの拡張性は今一つ、サーバサイド処理になる
Visualforceを使う

ええと、Lightning Championの立場からしたらお勧めしかねるのですが、ある意味最も堅実な選択肢です。

だってこれClassicでも動くんだもの!!

UIコンポーネントが充実しているLWCと異なり陳腐化したApexマークアップしか使えないVisualforceではありますが、自分でJavascriptフレームワークを導入すれば大した問題ではありません。

マークアップを極力使わず、Javascript主体で処理を行いApexもRemoteActionから呼ぶようにすればLightningコンポーネントと遜色ない処理はできてしまいます。

上のサンプルコードでも、Auraコンポーネント部分をVFに挿げ替えられるように作ってました。Apexクラスは簡単に共有化できますよ!

  • メリット:なんだかんだ好きに書けるので潰しが効く
  • デメリット:あるか?(Classic使わない人は覚えないでいいのでは)

あとがき

・・・てな感じで、画面作成のプラットフォームとしてはLWCが最先端で、Visualforceが根強く残り、Auraはその狭間でレガシーとして細々と存在している状態です。

今更習得するメリットは正直ほとんどないのですが、与太話として思い出して頂ければ幸いです。

さて、LWCの勉強せねば・・・

Japan Dreamin'2020 での発表内容のふりかえり(後編:Lightning Experienceモバイルのご紹介)

※この記事は「Japan Dreamin'2020 での発表内容のふりかえり(前編:発表内容のご紹介)」の続きとなります。

 

前回のあらすじ

出先でサクっとデータ見たい → アプリ誕生

どうせならちょこっと追記したい → Chatter

モバイルアプリとしてしっかり使えるように → SF1

PCとモバイル分断されてね? → LEX

↑いまここ

LEXモバイルの主な変更点について

大まかに、以下3要素が追加されております。いずれもPC版LEXに存在したものがモバイルで使えるようになった感じのものです。

  • アプリケーションランチャー
  • Lightningモバイルページ
  • ナビゲーション

では一つずつ見ていきましょう。

 

アプリケーションランチャー

f:id:hatamoto-t:20200528033426p:plain

メニュー画面の最上に「アプリケーションランチャー」が表示されています

PC版LEXで使える「アプリケーション」が選択できるようになっています。

以前は設定画面の「Salesforce ナビゲーション」が唯一のメニュー画面定義だったのですが、これからは複数のアプリケーションから最適なものを適宜選択できるようになります。

旧来のナビゲーションで設定したメニューは便宜上「モバイル専用」アプリケーションとして選択できるようになってますので、これだけを使う場合は操作感は変わりません。

ただ折角なので、「アプリケーションマネージャ」からアプリケーションを作ってみてはいかがでしょうか!

その際「アプリケーションオプション」からモバイルで表示されるように設定してくださいね。でないと表示されません(以下)

 

f:id:hatamoto-t:20200528034243p:plain

モバイルデバイスを「電話」と書くのはいかがなものか・・・?

 

Lightningモバイルページ

LEXを活用する際のキモとなる「Lightningページ」もモバイル対応しました!

「Lightningアプリケーションビルダー」からモバイルに対応したページを作成できます。

一般的なモバイル画面の仕様に配慮して、コンポーネントが縦一列に表示されるレイアウトのみになります。

PCと共用、もしくはモバイル専用のいずれの形式でも作成できます。

f:id:hatamoto-t:20200528034636p:plain

上段に「デスクトップ」「電話」等を選ぶ選択リストがあります

 

ナビゲーション

従来、モバイルUIの固定表示領域は下部のアクション一覧のみだったのですが、上下各1行に変更されました!

アクション一覧が上部に移った代わりに、下部はアプリケーションメニューの上位4件が表示されます。

(この上位が優先表示される仕様はPC版LEXでもSpring'20から適用されています)

 

f:id:hatamoto-t:20200528035203p:plain

新旧レイアウト比較表

余談ですが、上段のアクション一覧はVisualforce画面では表示されません。アクションを使いたい場合は標準アプリケーションかレコードのページでご覧ください。弊社アプリどうしよう

あとがき

以上、新要素はこんな感じです。ぶっちゃけそのまま使ってもあまり支障はないはずなんですが、せっかく設定要素が増えたわけですしこれを機に最適な設定を見直すのも悪くないのではないのでしょうか。

今後はサクっと書ける単発小ネタとかにしようかな・・・

今後は長くなりすぎないように

Japan Dreamin'2020 での発表内容のふりかえり(前編:発表内容のご紹介)

すみません筆不精なもので今更な話題になってしまい・・・

ようやく首都圏でも緊急事態宣言が解除され、辛く(楽しく?)長いテレワーク生活が終わった方も多いのではないでしょうか。

ちなみに弊社は6月も原則テレワーク継続です!(しかも1月末から!)

 

そんなこんななコロナ禍が始まる直前、去る1/25に開催された「Japan Dreamin'2020」のお話を今更ながら振り替えってみます。

※約3000字になったので2分割しました。長すぎると離脱率上がるらしいです・・・

 

Japan Dreamin' とは?

Salesforceコミュニティによる(Salesforce社ではなく)、Salesforceユーザのためのカンファレンスイベントです。

www.japandreamin.com

2019年では参加者100名程度だったのですが、今回はなんと300over、しかもセッションルームは4面同時進行という太っ腹対応!

そんなわけで、幸運にも1枠貰えましたので喋ってまいりました。

発表内容について

 発表スライドは↓です。

 

www.slideshare.net

このセッションでは「Salesforceのモバイル史」に焦点を当て、当時のモバイルデバイスの事情も絡めてWindowsPhone興亡の歴史モバイル用UIについての変遷を紹介してまいりました。

f:id:hatamoto-t:20200528022552p:plain

HPのElite x3、よく見ると「salesforce1」なるアプリが!?(実際はログイン画面に遷移するだけです)
(細かいけど)あらすじ

iPhoneソフトバンクから発売されたのが約10年前、それ以前からモバイルデバイス需要はわずかながら存在しました。SFの活動やレポート等を出先でも見られたら、というささやかなものから始まりました。

 

やがて現代的なスマートフォンの市場が確立につれ、「モバイルでもデータ入力できるべき!」という命題は避け得ぬものとなってまいります。

 

それに対するSalesforceの一つの解が「Chatter」でした。

フィード形式でコメントを添付することでチャットで会話ができたり、レコードにささやかなコメントを付けることができるようになったわけです。これがクローズドSNSのはしりとして、業務資料の共有にも役立っております。

フィードじゃなくて完全にチャット形式のメッセンジャーもありましたね。

(残念ながら廃止されました・・・)

また同時に実装された「パブリッシャーアクション」は独自の入力レイアウトを持つことができ、個々の編集目的に応じて必要最低限に最適化された入力フォームを呼び出しモバイルでも苦痛なくデータ入力ができるようになりました。(逆にPCだと使いづらいのですが・・・)

これらのモバイルUIの集大成として新機軸「Salesforce1」が誕生します。

Salesforce1はブラウザでもアプリでも利用でき、ページレイアウト・アクション・Visualforce等の様々なUIリソースを活用できるため、定常業務はこれで十分回せるかも!と思えるほどの高機能アプリになりました。

 

ただ言わせてもらうと、ChatterはともかくアクションはPCとの親和性がイマイチで、PCはPC、モバイルはモバイルでそれぞれ独自にカスタマイズしなければ使い物にならないのが実情だったと思います。データは同じですがUIは実質別システムなわけです。

 

そんな状況を打破する新UIこそが「Lightning Experience」(以下LEX)なのです!

Salesforce1用の既存リソースに加え、フローやLightninig Componentといった新しいリソースを含めPCとモバイルで共有できるようになりました。これから作成するリソースはどっちでも使えるんです。つまり無駄がない、エコです(!?)

f:id:hatamoto-t:20200528031254p:plain

みんな、使ってるよね?

 

で、最近Salesforceのモバイルアプリの見栄えが変わったのはご存じでしょうか・・・?

実はSpring'20よりモバイルアプリもLEX仕様に模様替えいたしました。

モバイルブラウザでは変わってません。これはなぜかというと、

モバイルブラウザでの閲覧(モバイルWeb)自体がSummer'20で廃止 されるからなんんですね・・・そんなわけで、いつもの如く否応なくこのアップデートはやってきます。まだブラウザを使っている方は要確認!!

皆さん実際に使ってみてどう思われたでしょうか?

「めちゃくちゃ変わった!?」「あんまり変わってなくね?」と感想は人それぞれだと思います。(自分は後者でした)

具体的にどのような変更が行われたのでしょうか。

 

以下後編へ続く

TeamSpirit Advent Calendar Day1:"Lightning Champion"ってなに?

この記事はチームスピリット Advent Calendar 2019の第1日目に掲載されます

 

皆様初めまして。チームスピリットのエンジニアリングチームに所属している畑本(id:hatamoto-t)です。

こちらの会社には2019年9月に入社しました。

本来は入社エントリという形でご挨拶すべきだったのですが、なんかいろいろ推敲してるうちに収拾がつかなくなって間に合わなかったので、ちょっとTec系での切り口から自己紹介を兼ねて記事を掲載させていただきます。

(今までブログとかやってなかったので、粗があるとこはご容赦ください・・・)

 

今回は、Salesforceの開発者プログラム"Lightning Champion"についてご紹介させていただきます。

"Lightning Champion"ってなに?

Lightning Championとは、Salesforce社が提供する製品の新機軸"Lightning Experience"(以下LEX)の普及を進めるエヴァンジェリスト的存在です。

https://droppinknowledge.files.wordpress.com/2018/09/champions.png

以下2種類のポジションがあります。

  • Lightning Activation Champion:Classic(旧UI)からLEXへの移行を支援
  • Lightning App Dev Champion:LEXに最適化されたアプリケーション開発を支援

私は"App Dev Champion"の方で昨年より活動しております。

詳細は以下をご覧ください。全世界のChampions達のプロフも閲覧できます。

(世界デビュー!?)

www.salesforce.com

ちなみに・・・Lightning Championは、Salesforceの社員ではありません。

金銭的報酬もありません。ちょっとビリッとしてる特注ユニフォームはもらえます。

(こんなの) 要するに名誉職です。見かけたら質問がてら労ってやってください。

 

つまり、何やってるの?

Lighting Experienceの普及活動を様々な手段で行っています。

  • ワークショップを開き活用方法を共有
  • ブログ、SNSで紹介記事を書く
  • ユーザの技術的困難に対する質疑応答

実のところ、LEXを普及させるにあたりSalesforceユーザには様々な課題が降りかかっています。

  • 昔作ったVisualforce画面やカスタムボタンが使えない
  • というか標準機能も使えない(ゴミ箱とか
  • じゃあその代わりにどうしたらいいのかわからない
  • LEXの画面がClassicより重い
  • うっかりリンクを押したらいきなり画面が変わって戻せない
  • そもそも、何で変えなきゃいけないの?Classicをずっと使わせて

・・・お気持ちは痛み入ります。私もそうでした。

じゃあ何でこんなことやってるの?

私も当初はLEXのことがよくわかっていませんでした。

以前はSIerSalesforce導入・運用支援に携わっていたのですが、現場での評価はやはり「LEXはまだ使えない、時期尚早」という感じでした。

けれどもこうも思うわけです。

「わからないから使えないのだ。ならば解ればまた違うのではないか」

そんな折、日本でのLightning Champion募集プログラムを知り、応募すると共にLEXについての学習を始めました。

その結果、以下のメリットが解ってきました。

  • LEXはページ遷移を伴わない、SPA(1ページで複数機能を満たすアプリケーション)的な使い方を想定したUIである
  • SPA化の実現のため、様々なコンポーネントを置ける「Lightningページ」を作成できる
  • 「パス」「Kanban」のような一覧性に優れたステータス管理機能の追加
  • モバイル画面で使っている「アクション」を使い、 PCとモバイルでリソースを共通化できる
  • 「Lightningフロー」でアプリケーションをノンコーディングで作成できる
  • 既存のVisualforceページもLightningページのアプリケーションとして活用できる
  • アプリ開発に「Lightningコンポーネント」を使えば、VisualforceよりもLEXとの親和性の高いアプリケーションが開発できる

これらの要素を知ることで、私の考えはこのように変化しました。

「せっかくこのような新機能が追加され続けているのに、活用しないでずっと同じ使い方をするなんてライセンス料がもったいない!(ぶっちゃけ安くはないです)

 

・・・LEXの活用法をレクチャーすることはあくまで手段に過ぎないです。

つまり、Lightning Championを続けるモチベーションはこんな感じです

  • LEX化は決して嫌がらせではない、きっと役に立つと認識してほしい
  • 実際に活用して、「便利になった」という驚きを共有したい
  • 解約を考えてる方にちょっと思いとどまってほしい
  • あと功名心

最後に

今回の記事では概要レベルでのご紹介しかできませんでしたが、これからLightning Experienceにまつわる様々な機能のご紹介や活動レポートを行いたいと思います。

今後ともよろしくお願いします。