LightningWebComponents lightning-datatableの使い方１（参照のみ）

# lightning-datatableの使い方

## 表示結果
![lightning-datatable.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559480/2b2ec177-b09b-0b6f-df3a-3e161705fc69.png)

- 取引先のレコードページへ追加
- LWCのapiVersionは47.0

## 使用した属性
- key-field
- data
- columns
- show-row-number-column
- hide-checkbox-column
- resize-column-disabled

### [Attribute] key-field
必須だが詳細がよくわからない...
Referenceには以下の記載あり。取り合えず "id" を指定しておけば良いのかな。
>Required for better performance. Associates each row with a unique ID.

### [Attribute] data
テーブルに表示する行の__データ配列__を指定する。
今回はSOQLで取得したリストが対象となる。（js側で少し加工するけど）

### [Attribute] columns
テーブルに表示する列の__データ型配列__を指定する。
Salesforce標準ではName項目は自動でリンクとなるが、lightning-datatableではそうならない。
もし同じような動きにしたければ、少し工夫が必要。
列の定義をtype=urlとし、データ取得時にダミー項目（CaseUrl）に加工したurlを設定してあげる。

```
{ label: 'ケース番号', fieldName: 'CaseUrl', type: 'url',
	typeAttributes: { label: { fieldName: 'CaseNumber' }, tooltip: { fieldName: 'CaseNumber' } } },
```

```
c.CaseUrl = '/lightning/r/' + c.Id + '/view';　←　「'/' + c.Id」のほうが汎用的だけど不要なリダイレクトが発生したのでやめた
```

また、fieldNameに取得したSOQLのカラムを指定すると自動でバインドされるが、クロスオブジェクト（例：Owner.Name）はサポートされていない（指定してもエラーにはならないが、空白表示となる）ため、こちらも少し工夫が必要となる。
urlと同様にデータ取得時にダミー項目（OwnerNameやContactName）にクロスオブジェクトを設定してあげるだけ。

```
{ label: '所有者', fieldName: 'OwnerUrl', type: 'url',
	typeAttributes: { label: { fieldName: 'OwnerName' }, tooltip: { fieldName: 'OwnerName' } } },
{ label: '取引先責任者', fieldName: 'ContactUrl', type: 'url',
	typeAttributes: { label: { fieldName: 'ContactName' }, tooltip: { fieldName: 'ContactName' } } },
```

```
c.OwnerName = c.Owner.Name;
c.ContactName = c.ContactId ? c.Contact.Name : '';　←　Ownerは必ず設定されるけど、ContactIdはそうではないため存在チェックしている
```

### [Attribute] show-row-number-column
行番号を表示したい場合に指定する。

### [Attribute] hide-checkbox-column
行選択のチェックボックスを非表示にしたい場合に指定する。

### [Attribute] resize-column-disabled
列のサイズ変更をさせたくない場合に指定する。

### Reference
[lightning-datatable](https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/specification "lightning-datatable")

## 気になった点
1. js側で加工したけどデータ量が多い場合はパフォーマンスに注意が必要そう。
1. columnsに指定する列のlabel名をリテラルで記載しているが、getObjectInfoを使えばスキーマ情報から取得できそう？
1. レコードページでコンポーネントが表示されない場合は、「私のドメイン」の設定とLWCのjs-meta.xmlの中身を確認。

## ソース
```CaseListVeiwController.cls
public with sharing class CaseListVeiwController {

	private CaseListVeiwController() {
	}

	@AuraEnabled
	public static List<Case> getCaseListVeiw(Id accountId) {
		return [
			SELECT
				Id,
				CaseNumber,
				TOLABEL(Status),
				TOLABEL(Priority),
				TOLABEL(Type),
				TOLABEL(Origin),
				TOLABEL(Reason),
				Subject,
				ClosedDate,
				OwnerId,
				Owner.Name,
				CreatedDate,
				CreatedById,
				LastModifiedDate,
				LastModifiedById,
				ContactId,
				Contact.Name
			FROM
				Case
			WHERE
				AccountId = :accountId
			ORDER BY
				LastModifiedDate DESC
		];
	}

}
```

```caseListVeiw.js
import { LightningElement, api, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

import getCaseListVeiw from '@salesforce/apex/CaseListVeiwController.getCaseListVeiw';

const columns = [
	{ label: 'ケース番号', fieldName: 'CaseUrl', type: 'url',
		typeAttributes: { label: { fieldName: 'CaseNumber' }, tooltip: { fieldName: 'CaseNumber' } } },
	{ label: '状況', fieldName: 'Status', type: 'text', },
	{ label: '優先度', fieldName: 'Priority', type: 'text', },
	{ label: '種別', fieldName: 'Type', type: 'text', },
	{ label: '発生源', fieldName: 'Origin', type: 'text', },
	{ label: '原因', fieldName: 'Reason', type: 'text', },
	{ label: '件名', fieldName: 'Subject', type: 'text', },
	{ label: '作成日', fieldName: 'CreatedDate', type: 'date',
		typeAttributes: { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' } },
	{ label: '完了日', fieldName: 'ClosedDate', type: 'date',
		typeAttributes: { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' } },
	{ label: '所有者', fieldName: 'OwnerUrl', type: 'url',
		typeAttributes: { label: { fieldName: 'OwnerName' }, tooltip: { fieldName: 'OwnerName' } } },
	{ label: '取引先責任者', fieldName: 'ContactUrl', type: 'url',
		typeAttributes: { label: { fieldName: 'ContactName' }, tooltip: { fieldName: 'ContactName' } } },
];

export default class CaseListVeiw extends LightningElement {

	@api recordId;
	@track columns = columns;
	@track records = [];
	@track loaded = false;

	connectedCallback() {
		getCaseListVeiw({
			accountId: this.recordId
		})
		.then(data => {
			data.forEach(c => {
				c.CaseUrl = '/lightning/r/' + c.Id + '/view';
				c.OwnerUrl = '/lightning/r/' + c.Owner.Id + '/view';
				c.OwnerName = c.Owner.Name;
				c.ContactUrl = c.ContactId ? '/lightning/r/' + c.ContactId + '/view' : '';
				c.ContactName = c.ContactId ? c.Contact.Name : '';
			});
			this.records = data;
			this.loaded = true;
		})
		.catch(error => {
			this.loaded = true;
			this.showToast(error.message);
		});
	}

	showToast(message) {
		const event = new ShowToastEvent({
			title: 'エラーが発生しました',
			message: message,
			variant: 'error',
			mode: 'pester'
		});
		this.dispatchEvent(event);
	}

	refresh(event) {
		this.loaded = false;
		this.connectedCallback();
	}

}
```

```caseListVeiw.html
<template>
	<lightning-card icon-name="standard:case">
		<h1 slot="title"><strong>取引先に紐づくケース</strong></h1>
		<lightning-button-icon slot="actions" icon-name="utility:refresh"  alternative-text="Refresh" onclick={refresh}></lightning-button-icon>
		<template if:true={records}>
			<div class="slds-m-around_x-small">
				<lightning-datatable
					key-field="id"
					data={records}
					columns={columns}
					show-row-number-column
					hide-checkbox-column
					resize-column-disabled>
				</lightning-datatable>
			</div>
		</template>
		<template if:false={loaded}>
			<lightning-spinner alternative-text="Loading"></lightning-spinner>
		</template>
	</lightning-card>
</template>
```