【Fiori】CDSビューでFiori Appを作る(2) UIアノテーション

##はじめに
CDSビューでFiori Appを作るシリーズの2回目で、今回はUIアノテーションを使って検索条件、リスト項目を定義します。

前回の記事はこちら
[【Fiori】CDSビューでFiori Appを作る](https://qiita.com/tami/items/1f63f0d3c46e3a0255e8)

##今回のゴール
- CDSビューに直接アノテーションを追加し、検索条件、リスト項目が表示されるようにします。
- Metadata extensionでアノテーションを外出しにして、同じ出力結果になるようにします。

##ステップ
1. UIアノテーションを追加
2. Metadata extensionでアノテーションを作成

##1. UIアノテーションを追加
###検索条件のアノテーション
@UI.selectionField を使います。positionという属性で表示する位置を指定し、数字が小さいものが左に表示されます。

```abap
    @UI.selectionField: [{position: 10 }]
    first_name, 
    @UI.selectionField: [{position: 20 }]
    last_name, 
    birthday, 
    region, 
    city, 
    street, 
    location, 
    created_at, 
    changed_at
```
アノテーションはJSON形式で記述します。書き方は色々あり、以下はいずれも同じ結果になります。

```abap
@UI: {        
    selectionField: [{position: 10 }]
}
@UI.selectionField: [{position: 10 }]
@UI.selectionField.position: 10
```

###リスト項目のアノテーション
@UI.lineItem を使います。検索条件と同じく、positionという属性で表示する位置を指定します。

```abap
    key student_id, 
    @UI.selectionField: [{position: 10 }]
    @UI.lineItem: [{position: 10 }]
    first_name, 
    @UI.selectionField: [{position: 20 }]
    @UI.lineItem: [{position: 20 }]
    last_name, 
    @UI.lineItem: [{position: 30 }]
    birthday, 
    @UI.lineItem: [{position: 40 }]
    region, 
    city, 
    street, 
    location, 
    created_at, 
    changed_at
```

###実行してみる
CDSビューを有効化してからFiori Appをリフレッシュします。
検索条件とリスト項目が最初から出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/be76d34f-5ba8-1940-8512-7f2ef5d7ce8d.png)

検索条件も効いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/fb6f0e67-7d98-73ae-98bb-176a0b97a068.png)

行を選択すると何もない画面に遷移しますが、アノテーションで簡単に詳細画面を作ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/fdfe67b2-42cc-a572-ab34-5d1d69baaaf6.png)

###詳細画面のアノテーション
@UI.identification を使います。
リストの項目に加えて、住所情報を表示させます。

```abap
    key student_id, 
    @UI.selectionField: [{position: 10 }]
    @UI.lineItem: [{position: 10 }]
    @UI.identification: [{position: 10}]
    first_name, 
    @UI.selectionField: [{position: 20 }]
    @UI.lineItem: [{position: 20 }]
    @UI.identification: [{position: 20}]
    last_name, 
    @UI.lineItem: [{position: 30 }]
    @UI.identification: [{position: 30}]
    birthday, 
    @UI.lineItem: [{position: 40 }]
    @UI.identification: [{position: 40}]
    region, 
    @UI.identification: [{position: 50}]
    city, 
    @UI.identification: [{position: 60}]
    street, 
    @UI.identification: [{position: 70}]
    location, 
    created_at, 
    changed_at
```

詳細画面に項目が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/98cfd911-ae1f-c141-3191-505e2ce6e9d2.png)

###ラベルをつけてみる
identificationの属性でlabelがあるので設定してみます。

```abap
    @UI.selectionField: [{position: 10 }]
    @UI.lineItem: [{position: 10 }]
    @UI.identification: [{position: 10, label: 'First Name'}]
    first_name, 
```

ラベルが表示されました。翻訳はどうするんだろう？
[こちらの記事](https://sapyard.com/cds-part-14-abap-annotations-for-translatable-texts-in-cds-views/)によると、SE63で翻訳できるそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/e89e29d9-8390-a7f1-887c-68d505cc2f09.png)

##2. Metadata extensionでアノテーションを作成
###Metadata extensionとは

CDSのソースからアノテーションを切り出したものをMetadata extensionといいます。これによってビューの定義とUIの定義を分離でき、ソースのモジュール化や見やすさの向上といったメリットがあります。

参考：[Modularizing CDS Annotations](https://blogs.sap.com/2016/10/19/modularizing-cds-annotations/)

###Metadata extensionを登録する
Projectフォルダー上で右クリックし、New>Other ABAP Repository Objectを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5f6f7004-7b50-4623-aef0-221976a7dbf4.png)
Metadata Extensionを検索し、次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/306c8e69-950c-0b79-8a90-be6fa5d7c017.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/e1fc4dec-0691-3653-5b3a-60da0f2908b4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/7acd1ee0-daba-dbf0-0a8e-6120cdf9b107.png)
以下のようなソースが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f115e757-1c06-d5df-763d-5d1a5581ee82.png)

###layerの指定
layerの文字を消してCtrl+Spaceを押すと、設定可能な候補が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b694fdb3-284b-6233-7d68-88bca50e915b.png)
ひとつのCDSビューに複数のMetadata Extensionがある場合にどれが採用されるかというと、#CORE ,#LOCALIZATION, #INDUSTRY, #PARTNER, #CUSTOMERの順に優先度が高くなります。（右に行くほど優先度が高い）
今回は#COREを選択します。

###UIアノテーションを移植
元のビューからUIアノテーションの部分をコピーして移植します。この際、項目の区切りはカンマではなくセミコロンになります。

```abap
@Metadata.layer: #CORE
annotate view ZMOB58_C_STUDENTS
    with 
{
    @UI.selectionField: [{position: 10 }]
    @UI.lineItem: [{position: 10 }]
    @UI.identification: [{position: 10, label: 'First Name'}]
    first_name; 
    @UI.selectionField: [{position: 20 }]
    @UI.lineItem: [{position: 20 }]
    @UI.identification: [{position: 20, label: 'Last Name'}]
    last_name; 
    @UI.lineItem: [{position: 30 }]
    @UI.identification: [{position: 30, label: 'Birthday'}]
    birthday; 
    @UI.lineItem: [{position: 40 }]
    @UI.identification: [{position: 40, label: 'Region'}]
    region; 
    @UI.identification: [{position: 50, label: 'City'}]
    city; 
    @UI.identification: [{position: 60, label: 'Street'}]
    street; 
    @UI.identification: [{position: 70, label: 'Location'}]
    location;
}
```

**2020/11/13追加**
Business Application Studio (Fiori Tools)でアプリを作成する場合、先頭に`@UI.facet`アノテーションを追加してください。こうしないとObject PageにIdentificationの情報が表示されません。

```abap
annotate view ZMOB58_C_STUDENTS
    with 
{
    @UI.facet: [{ 
      id: 'general',
      type: #IDENTIFICATION_REFERENCE,
      purpose: #STANDARD,
      label: 'General Information',
      targetQualifier: 'generalGroup'
    }]
    ...
```



###元のビューの修正
元のビューには以下の変更を加えます。

- @Metadata.allowExtensions: trueを設定する
- UIアノテーションを削除する

```abap
@AbapCatalog.sqlViewName: 'ZMOB58_V_STUDENT'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Students CDS for Fiori'
@OData.publish: true
@Metadata.allowExtensions: true
define view ZMOB58_C_STUDENTS as select from zstudents {

    //zstudents 
    key student_id, 
    first_name, 
    last_name, 
    birthday, 
    region, 
    city, 
    street, 
    location, 
    created_at, 
    changed_at    
}
```
以上の変更を行った後、元のビューとMetadata Extensionを有効化します。

###実行結果
変更前と同じ結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/772ad56f-75ef-74d4-8007-05e070ad8e72.png)

Metadata Extensionに検索項目を追加してみます。

```abap
    @UI.selectionField: [{position: 30 }]
    @UI.lineItem: [{position: 40 }]
    @UI.identification: [{position: 40, label: 'Region'}]
    region; 
```

検索条件が追加されました。Metadata Extensionがちゃんと動いていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/69f5be03-8909-d404-594c-277b12981f14.png)


##今回のまとめ

- UIアノテーションで画面項目を定義することができる
- Metadata Extensionを使ってUIアノテーションをCDSのソースから分離することができる

##参考
[Modularizing CDS Annotations](https://blogs.sap.com/2016/10/19/modularizing-cds-annotations/)
[ABAP News for Release 7.51 – Meta Data Extensions in ABAP CDS](https://blogs.sap.com/2016/10/25/abap-news-release-7.51-meta-data-extensions-abap-cds/)
[CDS Part 14. ABAP Annotations fo](https://sapyard.com/cds-part-14-abap-annotations-for-translatable-texts-in-cds-views/)