Salesforce タブ操作をするAuraコンポーネントを作ってみた

# これは何？
この記事は「[24日後に立派なSalesforceエンジニアになるWEBエンジニア Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kakakaori)」の19日目の記事です6日後に立派なSalesforceエンジニアになるために今日からはタブの制御を通してAuraコンポーネントについて学んでいきます。

# どの機能を使う？
Salesforceにはタブ（もしくは主タブ）と呼ばれるものとサブタブと呼ばれるものがあり、私たちもこの機能をよく使っている。
![スクリーンショット 2022-12-14 16.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200812/e978e139-e991-2f65-6b84-58a1d86924f3.png)
しかしこのタブの制御をプログラムから行おうとするとLWCではまだサポートされていないので、Auraで実装する必要がある。今回はいくつかこのタブの制御を作りながらAuraコンポーネントへの理解を深めていく。

Salesforceにおけるタブの操作については[Lightning Experience のワークスペースタブとサブタブのメソッド](https://developer.salesforce.com/docs/atlas.ja-jp.api_console.meta/api_console/sforce_api_console_methods_lightning_workspaceAPI.htm)に詳しく書かれているので、それを参考にしながらサンプルプログラムを作っていく。

# 何を作る？
ホーム画面を開いた時に、赤枠内にあるように2つのタブを自動で表示するものを作る。よく使う特定のページなどを必ず開いておきたい時とかに使う想定。
![スクリーンショット 2022-12-14 21.52.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200812/8e4498bd-4a98-000f-e13e-7210fc823144.png)

全体の流れとしてはレンダリング時にタブを開く処理を書いたAuraコンポーネントを作って、ホーム画面のLightningアプリケーションビルダーからコンポーネントを配置する。このコンポーネント自体は目にみえる要素はないのでどの位置に配置しても良い。そうすることでホームページを開いた時に事前に指定しておいたタブが表示されるようになる。

## 作り方

### コンポーネント
コンポーネントはinitイベントでコントローラーのイベントを呼び出すように定義しておく。タブの制御を行うためには`lightning:workspaceAPI`を読み込んでおく必要があるのでコンポーネント内に記載する。

```html:
  <aura:handler name="init" value="{!this}" action="{!c.openTab}" />
  <lightning:workspaceAPI aura:id="workspace" />
```

また今回作ったAuraコンポーネントを埋め込みたいのは表示したいのはレコードページではなくてホーム画面なので`implements`は`flexipage:availableForAllPageTypes`を指定しておく。

```html:
<aura:component implements="flexipage:availableForAllPageTypes" access="global">

</aura:component>
```

### コントローラー
コンポーネントの`init`イベントでコントローラーの`openTab`メソッドを呼び出すようにしているので`openTab`メソッドを定義して、タブを表示する処理を書いていく。
タブを表示する処理は[Lightning Experience の openTab()](https://developer.salesforce.com/docs/atlas.ja-jp.api_console.meta/api_console/sforce_api_console_lightning_opentab.htm)に記載があるからそれに従う。指定する遷移先については`pageReference`を指定してもいいし`url`を指定しても良いが、今回は`url`パラメータを指定する。
```javascript:
    var workspaceAPI = component.find("workspace");
    workspaceAPI
      .openTab({
        url: url,
        focus: false
      })
      .then(function (response) {
        workspaceAPI.setTabIcon({
          tabId: response,
          icon: iconName; 
        });
      })
      .catch(function () {});
```
せっかくなので開いたタブにアイコンを表示しておきたかったので[setTabIcon](https://developer.salesforce.com/docs/atlas.en-us.api_console.meta/api_console/sforce_api_console_lightning_setTabIcon.htm)を使ってみた。

### 完成
```html:test.cmp
<aura:component implements="flexipage:availableForAllPageTypes" access="global">
  <aura:handler name="init" value="{!this}" action="{!c.openTab}" />
  <lightning:workspaceAPI aura:id="workspace" />
</aura:component>
```

```javascript:testController.js
({
  openTab: function (component) {
    var menuList = [
      {
        url: "/lightning/o/Case/home",
        icon: "utility:case"
      },
      {
        url: "/lightning/o/Task/home",
        icon: "utility:task"
      }
    ];

    var workspaceAPI = component.find("workspace");
    workspaceAPI
      .openTab({
        url: url,
        focus: false
      })
      .then(function (response) {
        workspaceAPI.setTabIcon({
          tabId: response,
          icon: iconName; 
        });
      })
      .catch(function () {});
  }
});
```

# 補足
上記では主タブの操作を行なっているが基本的に同じような形でサブタブの操作も行うことができる。
ただしサブタブの場合は、どのタブの下に開くのかを指定しなくてはいけないので、手順として今開いているタブIDを取得し、その後そのタブIDを引数に渡してサブタブを開くという流れになる。
コードとしては該当箇所だけピックアップすると以下のような感じ。
```javascript:testController.js
var workspaceAPI = component.find("workspace");
// これで今開いているタブの情報を取得する
workspaceAPI.getFocusedTabInfo().then(function (response) { 
  workspaceAPI
    .openSubtab({
      parentTabId: response.tabId, // サブタブをどの主タブの下に表示するかを指定
      url: url,
      focus: true
    })
    .then(function (subtabResponse) {
      workspaceAPI.setTabLabel({ // サブタブのラベルを変更する場合はこんな感じ
        tabId: subtabResponse,
        label: label
      });
    });
});
```

# 最後に
今回はAuraコンポーネントの具体的な活用方法としてタブの操作についてみていきました。Auraコンポーネントはあまり積極的に使っていきたくないものの、まだまだLWCで実装できない部分についてはAuraに頼る必要がありそうです。
明日はまだSOQLについて触れてこなかったのでSOQLについて学んでいきたいと思います。