29 · Fiori UI Annotations

Add @UI.LineItem, @UI.HeaderInfo, @UI.Facets, @UI.FieldGroup, and value help annotations for Fiori Elements rendering.

Episode 29 — Fiori UI Annotations in CAP

What you'll learn

Why this matters

Fiori Elements generates the full UI from annotations — no custom JavaScript needed for standard layouts. Getting these annotations right means the UI builds itself. Getting them wrong means hours debugging why your Object Page has no fields.

The Fiori Elements pattern

CDS Entity  →  Service Projection  →  Annotations  →  Fiori Elements renders UI

Annotations live in the service layer (or a separate .cds file), not on the DB entity.

List Report annotations

// srv/annotations.cds
using OrdersService as svc from './orders-service';

annotate svc.Orders with @(
  UI.LineItem: [
    { Value: ID,          Label: 'Order ID'   },
    { Value: buyer.name,  Label: 'Buyer'      },
    { Value: status,      Label: 'Status'     },
    { Value: total,       Label: 'Total'      },
    { Value: createdAt,   Label: 'Created'    },
    {
      $Type:  'UI.DataFieldForAction',
      Action: 'OrdersService.submitOrder',
      Label:  'Submit'
    }
  ],
  UI.SelectionFields: [ status, createdAt, buyer_ID ],
  UI.PresentationVariant: {
    SortOrder: [{ Property: createdAt, Descending: true }]
  }
);

Object Page — HeaderInfo

annotate svc.Orders with @(
  UI.HeaderInfo: {
    TypeName:       'Order',
    TypeNamePlural: 'Orders',
    Title:          { Value: ID },
    Description:    { Value: buyer.name }
  }
);

Object Page — Facets & FieldGroups

annotate svc.Orders with @(
  UI.Facets: [
    {
      $Type:  'UI.ReferenceFacet',
      ID:     'GeneralInfo',
      Label:  'General Information',
      Target: '@UI.FieldGroup#GeneralInfo'
    },
    {
      $Type:  'UI.ReferenceFacet',
      ID:     'Items',
      Label:  'Order Items',
      Target: 'items/@UI.LineItem'
    }
  ],
  UI.FieldGroup#GeneralInfo: {
    Data: [
      { Value: status,     Label: 'Status'       },
      { Value: total,      Label: 'Total Amount'  },
      { Value: notes,      Label: 'Notes'         },
      { Value: createdAt,  Label: 'Created At'    }
    ]
  }
);

Value help (dropdown)

// Enum-based value help from a Currencies entity
annotate svc.Orders with {
  currency @(
    Common.ValueList: {
      CollectionPath: 'Currencies',
      Parameters: [
        { $Type: 'Common.ValueListParameterOut', LocalDataProperty: currency_code, ValueListProperty: 'code' },
        { $Type: 'Common.ValueListParameterDisplayOnly', ValueListProperty: 'name' }
      ]
    },
    Common.ValueListWithFixedValues: true
  )
}

Status criticality (colour coding)

annotate svc.Orders with {
  statusCriticality @UI.Hidden;   // used internally, not shown as column
}

annotate svc.Orders with @(
  UI.LineItem: [
    {
      Value:       status,
      Criticality: statusCriticality   // 1=grey, 2=red, 3=orange, 4=green
    }
  ]
);
// Computed in AFTER handler
this.after('READ', 'Orders', (orders) => {
  orders.forEach(o => {
    o.statusCriticality = { DRAFT: 0, SUBMITTED: 2, SHIPPED: 3, DELIVERED: 4 }[o.status] ?? 0
  })
})

Navigation properties (associations in LineItem)

annotate svc.OrderItems with @(
  UI.LineItem: [
    { Value: book.title,   Label: 'Book'      },
    { Value: quantity,     Label: 'Quantity'  },
    { Value: price,        Label: 'Price'     }
  ]
);

Separate annotation file pattern

srv/
├── orders-service.cds        ← service definition
├── orders-service.js         ← handlers
└── fiori/
    ├── orders-annotations.cds  ← Fiori annotations
    └── catalog-annotations.cds
// srv/fiori/orders-annotations.cds
using OrdersService as svc from '../orders-service';
// all @UI, @Common, @Communication annotations here

Hands-on exercise

  1. Annotate your Books service with @UI.LineItem (title, author, price, stock)
  2. Add @UI.HeaderInfo with title=title, description=author_name
  3. Add an Object Page with two facets: General Info (price, stock) and Description
  4. Add a value help for genre from a Genres entity
  5. Open the Fiori preview in cds watch and verify the layout

Checkpoint ✓

Sign in for progress tracking & Q&A →