**TITLE**: In/Out Mappings in the Common.ValueList Annotation (OData/Fiori Elements)

**INTRODUCTION**: This document explains how to configure Common.ValueList with IN/OUT (and INOUT) parameter mappings to connect properties in the main entity with properties in the value help (value list) entity. It includes actionable examples for XML annotations, ABAP CDS, and CAP CDS. Use these mappings to:
- apply main-entity filter values to the value help dataset (IN),
- write back selected value help fields to main-entity properties (OUT),
- combine both behaviors (INOUT).

Note: In SAP Fiori elements for OData V2, IN/OUT mappings are supported only for Analytical List Page. OUT parameters are applied for filter fields only if the LocalDataProperty is visible in the filter bar.

**TAGS**: fiori-elements-framework, OData, ValueList, ValueHelp, annotation, Common.ValueList, Common.ValueListParameterIn, Common.ValueListParameterOut, CDS, CAP, ABAP

STEP: 1 — Annotation terms and definitions

DESCRIPTION: Key annotation terms used to map properties between main entity and value list entity. Use these definitions when authoring ValueList parameter records.

LANGUAGE: text

CODE:
```text
Common.ValueListParameterIn:   Determines a main-entity property taken into the filter query of the value help entity (applies main->valueHelp filters).
Common.ValueListParameterOut:  Determines which value help property sets the main-entity property when a user selects a value (applies valueHelp->main writeback).
Common.ValueListParameterInOut: Combines both IN and OUT behaviors.
LocalDataProperty:            Property in the main entity (the entity where the field is defined).
ValueListProperty:            Property in the value help entity (provides values for LocalDataProperty or is filtered by it).
Tip: OUT parameters for filter fields are applied only if the target LocalDataProperty is visible in the filter bar.
Note: OData V2 - IN/OUT supported only for Analytical List Page.
```

STEP: 2 — Define selection/filter fields on the main entity

DESCRIPTION: Declare which fields appear in the selection bar (filter fields) of the list report / ALP. Examples in XML, ABAP CDS and CAP CDS.

LANGUAGE: XML

CODE:
```xml
<Annotation Term="UI.SelectionFields">
	<Collection>
		<PropertyPath>RegionID</PropertyPath>
		<PropertyPath>CountryID</PropertyPath>
		<PropertyPath>PlantID</PropertyPath>
	</Collection>
</Annotation>
```

LANGUAGE: ABAP CDS

CODE:
```abap
@UI.SelectionField: [
  {
    position: 1 ,
    element: 'REGIONID'
  }
]
REGIONID;

@UI.SelectionField: [
  {
    position: 2 ,
    element: 'COUNTRYID'
  }
]
COUNTRYID;

@UI.SelectionField: [
  {
    position: 3 ,
    element: 'PLANTID'
  }
]
PLANTID;
```

LANGUAGE: CAP CDS

CODE:
```cds
UI.SelectionFields : [
    RegionID,
    CountryID,
    PlantID
]
```

STEP: 3 — ValueList opening / target declaration (example for CountryID)

DESCRIPTION: Start a ValueList annotation for CountryID on the Z0020 main entity. Use CollectionPath to point to the value help entity and add Parameters collection to list IN/OUT mappings.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="Z0020_CDS.Z0020Type/CountryID">
    <Annotation Term="Common.ValueList" Qualifier="0020_Country">
```

STEP: 4 — OUT parameter example (explain behavior)

DESCRIPTION: OUT parameter maps which value from the value help is written into the main-entity property when the user selects a value. LocalDataProperty is the target main-entity property; ValueListProperty is the value help property used as the displayed/selected value. The selection result (LocalDataProperty) drives subsequent filter queries on the main entity ($filter=CountryID="001").

LANGUAGE: XML

CODE:
```xml
<Record Type="Common.ValueListParameterOut">
    <PropertyValue Property="LocalDataProperty" PropertyPath="CountryID"/>
    <PropertyValue Property="ValueListProperty" String="CountryIdentifier"/>
</Record>
```

STEP: 5 — IN parameter example (explain behavior)

DESCRIPTION: IN parameter filters the value help dataset using the main-entity value. LocalDataProperty is read from the main entity and applied as a filter on ValueListProperty in the value help entity (main->valueHelp filter).

LANGUAGE: XML

CODE:
```xml
<Record Type="Common.ValueListParameterIn">
    <PropertyValue Property="LocalDataProperty" PropertyPath="RegionID"/>
    <PropertyValue Property="ValueListProperty" String="RegionIdentifier"/>
</Record>
```

STEP: 6 — Complete XML ValueList example for CountryID (XML)

DESCRIPTION: Complete ValueList annotation for CountryID on Z0020. It:
- points to value help entity Z0022,
- disables search support,
- defines an OUT mapping CountryID <- CountryIdentifier,
- defines an IN mapping RegionID -> RegionIdentifier.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="Z0020_CDS.Z0020Type/CountryID">
    <Annotation Term="Common.ValueList" Qualifier="0020_Country">
        <Record>
            <PropertyValue Property="Label" String="Country"/>
            <PropertyValue Property="CollectionPath" String="Z0022"/>
            <PropertyValue Property="SearchSupported" Bool="false"/>
            <PropertyValue Property="Parameters">
                <Collection>
                    <Record Type="Common.ValueListParameterOut">
                        <PropertyValue Property="LocalDataProperty" PropertyPath="CountryID"/>
                        <PropertyValue Property="ValueListProperty" String="CountryIdentifier"/>
                    </Record>
                    <Record Type="Common.ValueListParameterIn">
                        <PropertyValue Property="LocalDataProperty" PropertyPath="RegionID"/>
                        <PropertyValue Property="ValueListProperty" String="RegionIdentifier"/>
                    </Record>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

STEP: 7 — Equivalent ABAP CDS ValueHelp definition for CountryID

DESCRIPTION: ABAP CDS consumption annotation that maps CountryID (result) and RegionID (filter) for entity Z0022. usage: #RESULT corresponds to Common.ValueListParameterOut; usage: #FILTER corresponds to Common.ValueListParameterIn.

LANGUAGE: ABAP CDS

CODE:
```abap
@Consumption.valueHelpDefinition:
        [{
          entity :{
            name    : 'Z0022'
          },
            label  : 'Country',
            additionalBinding: [
              {
                localElement: 'CountryID',
                element: 'CountryIdentifier',
                usage: #RESULT // Common.ValueListParameterOut
               },
 {
                localElement: 'RegionID',
                element: 'RegionIdentifier',
                usage: #FILTER // Common.ValueListParameterIn
               }
            ]
          }
         ]
CountryID;
```

STEP: 8 — Equivalent CAP CDS ValueList definition for CountryID

DESCRIPTION: CAP CDS annotation example that declares a Common.ValueList with an OUT parameter and an IN parameter. Useful when modeling in CAP (CDS for Node.js).

LANGUAGE: CAP CDS

CODE:
```cds
CountryID : UUID @(
    Common : {
        ValueList #0020_Country : {
            Label : 'Country',
            CollectionPath : 'Z0022',
            Parameters : [
            {
                $Type : 'Common.ValueListParameterOut',
                LocalDataProperty : CountryID,
                ValueListProperty : 'CountryIdentifier'
            },
            {
                $Type : 'Common.ValueListParameterIn',
                LocalDataProperty : RegionID,
                ValueListProperty : 'RegionIdentifier'
            }
            ]
       }
    }
);
```

STEP: 9 — ValueList for PlantID with multiple IN parameters (XML)

DESCRIPTION: Example ValueList annotation for PlantID that:
- reads plant values from Z0023 (PlantNumber),
- writes selected PlantNumber into PlantID (OUT),
- filters the plant value help by Region and Country (two IN parameters mapped to RegionNumber and CountryNumber).

LANGUAGE: XML

CODE:
```xml
<Annotations Target="Z0020_CDS.Z0020Type/PlantID">
    <Annotation Term="Common.ValueList" Qualifier="0020_Plant">
        <Record>
            <PropertyValue Property="Label" String="Plant"/>
            <PropertyValue Property="CollectionPath" String="Z0023"/>
            <PropertyValue Property="SearchSupported" Bool="false"/>
            <PropertyValue Property="Parameters">
                <Collection>
                    <Record Type="Common.ValueListParameterOut">
                        <PropertyValue Property="LocalDataProperty" PropertyPath="PlantID"/>
                        <PropertyValue Property="ValueListProperty" String="PlantNumber"/>
                    </Record>
                    <Record Type="Common.ValueListParameterIn">
                        <PropertyValue Property="LocalDataProperty" PropertyPath="RegionID"/>
                        <PropertyValue Property="ValueListProperty" String="RegionNumber"/>
                    </Record>
                    <Record Type="Common.ValueListParameterIn">
                        <PropertyValue Property="LocalDataProperty" PropertyPath="CountryID"/>
                        <PropertyValue Property="ValueListProperty" String="CountryNumber"/>
                    </Record>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

STEP: 10 — Expected runtime behaviors and sample filter query

DESCRIPTION: Practical outcomes of mapping:
- OUT mapping: a value selected in the value help (ValueListProperty) is written into the main property (LocalDataProperty). Filtering on the main entity uses the LocalDataProperty (e.g., $filter=CountryID="001").
- IN mapping: if RegionID = "ABC" is present in the selection, the Country value help applies filter RegionIdentifier="ABC" and only countries for that region are shown.
- Combining INs on PlantID ensures the Plant value help shows only plants that belong to both selected Region and Country (if both present).

LANGUAGE: text

CODE:
```text
Example: user selects CountryIdentifier = "001" in the Country value help.
Result: main-entity CountryID <- "001" and main query uses $filter=CountryID="001" (not CountryIdentifier).
Example: RegionID = "ABC" in filter bar + Country value help opened:
Value help backend filter applied: $filter=RegionIdentifier eq 'ABC' (filters countries to that region).
Plant value help when both RegionID and CountryID present:
Value help backend receives both filters (RegionNumber and CountryNumber) and returns only plants matching both.
```

fiori-elements-framework OData ValueList ValueHelp annotation Common.ValueList Common.ValueListParameterIn Common.ValueListParameterOut CDS CAP ABAP


**TITLE**: Embedding Reuse Components into an Object Page (SAP Fiori elements)

**INTRODUCTION**: This document shows how to embed reuse components as sections on an Object Page in SAP Fiori elements apps (OData V2 and OData V4). It provides actionable manifest.json examples and explains key properties you must set: id, componentUsage vs componentName, title (i18n), settings bindings, binding context, default visibility (hiddenByDefault + extensionAPI setSectionHidden), placement, and dependency declarations.

**TAGS**: fiori-elements-framework, reuse-component, manifest.json, sapui5, odata-v2, odata-v4, object-page, embeddedComponents

STEP: Embed reuse components on an Object Page (OData V2)

DESCRIPTION: Add reuse component instances in the "sap.ui.generic.app" -> "pages" -> ObjectPage entry of your app's manifest.json. Choose one of two addressing options:
- componentUsage: reference a component usage configured elsewhere (recommended when using createComponent API).
- componentName: address the fully qualified component name directly.

Key requirements:
- The property name inside embeddedComponents and the id inside that definition must be identical.
- Use "title" pointing to an i18n key for a translatable section title.
- Use "settings" to pass property bindings to the reuse component (any valid binding string, including expression bindings).
- Use "binding" to adjust the binding context for the reuse component instance; the path is relative to the page binding context.

LANGUAGE: JSON

CODE:
```json
...
 "sap.ui.generic.app": {
    ...
    "pages": {
        "ListReport|myRootEntity": {

            "entitySet": "myRootEntity",
            "component": {
                "name": "sap.suite.ui.generic.template.ListReport",
                "list": true,
                ...
            },
            "pages": {
                "ObjectPage|myRootEntity": {
                    "entitySet": "myRootEntity",
                    "component": {
                        "name": "sap.suite.ui.generic.template.ObjectPage",
                        ...
                    },
                    "embeddedComponents": {
                        "myFirstComponentEmbedding": {
                            "id": "myFirstComponentEmbedding",
                            "componentUsage": "myUsage",
                            "title": "{{I18N_KEY_FOR_FIRST_REUSE_COMPONENT_TITLE}}",
                            "settings": {
                                "documentNumber": "{documentNumber}"
                            }
                        },
                        "mySecondComponentEmbedding": {
                            "id": "mySecondComponentEmbedding",
                            "componentName": "theOtherReuseComponentQualifiedName",
                            "title": "{{I18N_KEY_FOR_SECOND_REUSE_COMPONENT_TITLE}}",
                            "binding": "myNavProperty",
                        }
                    },
                    "pages": {
                        // add list of sub-pages of the root object page here
                    }
                }
            }
        }
    }
```

STEP: Visibility control and lifecycle (OData V2)

DESCRIPTION: Control default visibility and dynamic show/hide:
- hiddenByDefault: set on the same level as id/title/settings. If true, the section is hidden when the page opens for a new instance.
- Use the reuse component's extensionAPI method setSectionHidden(false/true) inside the reuse component implementation to unhide or hide the section at runtime based on instance data.
- Default hiddenByDefault should reflect the most common scenario; then unhide for specific instances.

LANGUAGE: JavaScript (conceptual usage)

CODE:
```javascript
// In your reuse component controller or extension code (conceptual)
this.extensionAPI.setSectionHidden(false); // show the section
this.extensionAPI.setSectionHidden(true);  // hide the section
```

STEP: Binding context behavior (OData V2)

DESCRIPTION: The embedding page's OData model binding context is inherited by the reuse component. Use the "binding" property on the embedding definition to modify the binding context for a specific reuse component instance. The binding path is relative to the page's current binding context.

LANGUAGE: JSON (example excerpt)

CODE:
```json
"mySecondComponentEmbedding": {
    "id": "mySecondComponentEmbedding",
    "componentName": "theOtherReuseComponentQualifiedName",
    "title": "{{I18N_KEY_FOR_SECOND_REUSE_COMPONENT_TITLE}}",
    "binding": "myNavProperty"
}
```

STEP: Placement and Adaptation (OData V2)

DESCRIPTION: Each embedded component instance is rendered as an Object Page section -> sub-section -> content. By default they are appended in the order defined in manifest.json. You can reposition them using the Adaptation Editor or placement APIs. For advanced placement options, consult placing-reuse-component-instances-on-the-object-page.

LANGUAGE: N/A

CODE:
```text
// Placement is controlled via Adaptation Editor or by changing the order of entries
// in the manifest. No manifest code required here beyond embeddedComponents order.
```

STEP: Declare component OData/service dependencies (OData V2)

DESCRIPTION: If the reuse component uses its own OData service or libraries, declare these dependencies in the host app manifest under both:
- "sap.ui5" -> "dependencies" -> "libs"
- "sap.ui5" -> "dependencies" -> "components"

This ensures libraries and component dependencies are loaded.

LANGUAGE: JSON (conceptual)

CODE:
```json
{
  "sap.ui5": {
    "dependencies": {
      "libs": {
        "sap.m": {}
      },
      "components": {
        "path.to.reuseComponent": {}
      }
    }
  }
}
```

STEP: Embed reuse components on an Object Page (OData V4 — preferred approach)

DESCRIPTION: For OData V4, prefer embedding via the routing target options/settings content body sections. Use "embeddedComponent" with "name" and "settings" under a section declaration. Use "position" (placement and anchor) to place the section relative to other sections. Provide title as i18n binding.

LANGUAGE: JSON

CODE:
```json
{
    "sap.ui5": {
        "routing": {
            "routes": [
                {
                    "pattern": "myEntitySet({key}):?query:",
                    "name": "myObjectPage",
                    "target": "myObjectPage"                }
            ],
            "targets": {
                "myObjectPage": {
                    "options": {
                        "settings": {
                            "content": {
                                "body": {
                                    "sections": {
                                        "customSectionReuse": {
                                            "title": "{i18n>customSectionReuse}",
                                            "embeddedComponent": {
                                                "name": "path.to.reuseComponent",
                                                "settings": {
                                                    "exampleSettings": "{somePropertyName}"                                                }
                                            },
                                            "position": {
                                                "placement": "After",
                                                "anchor": "someOtherSection"                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

STEP: Embed reuse components on an Object Page (OData V4 — alternative using routing targets)

DESCRIPTION: Alternative: add a target entry of type Component for the reuse component and attach it to the Object Page target via the "target" array on the route. Use "controlId" and "controlAggregation" to place the component inside a container section. Set "clearControlAggregation" if you want to replace existing aggregation contents.

LANGUAGE: JSON

CODE:
```json
{
	"sap.ui5": {
		"routing": {
			"routes": [
				{
					"pattern": "myEntitySet({key}):?query:",
					"name": "myObjectPage",
					"target": ["myObjectPage", "ReuseComponent"]
				}
			],
			"targets": {
				"myObjectPage": {
					"type": "Component",
					"id": "myObjectPage",
					"name": "sap.fe.templates.ObjectPage",
					"options": {
						"settings": {
							"content": {
								"body": {
									"sections": {
										"ReuseComponentContainer": {
											"position": {
												"placement": "Before",
												"anchor": "GeneralInfo"
											},
											"title": "Reuse Container",
											"subSections": {
												"ReuseContainer": {
													"id": "ReuseComponentContainer"
												}
											}
										}
									}
								}
							}
						}
					}
				},
				"ReuseComponent": {
					"type": "Component",
					"id": "Reuse",
					"name": "path.to.reuseComponent",
					"options": {
						"settings": {
							"exampleSettings": "{somePropertyName}"
						}
					},
					"parent": "myObjectPage",
					"controlId": "ReuseComponentContainer",
					"controlAggregation": "blocks",
					"clearControlAggregation": true
				}
			}
		}
	}
}
```

STEP: Visibility expression for OData V4

DESCRIPTION: For OData V4 reuse components, use standard SAPUI5 visible bindings. To show a component only when a field has a value (example: SalesOrder), set visible to an expression binding.

LANGUAGE: JSON (binding example)

CODE:
```json
"visible": "{= !!${SalesOrder} }"
```


**TITLE**: Influence Table Binding Requests Dynamically with beforeRebindTable (Fiori Elements OData V4)

**INTRODUCTION**: Add dynamic filters, sorters, and selected properties to table OData requests before the table rebinding occurs. Use the beforeRebindTable extension on table settings (manifest.json) and implement a controller extension to modify the CollectionBindingInfo API. Also shows how to retrieve the table row count (getCount) and update UI controls after data is received or refreshed.

**TAGS**: fiori-elements, odata-v4, beforeRebindTable, table, controller-extension, ui5, collectionBindingInfo, getCount

**STEP**: 1. Add beforeRebindTable key to table settings in manifest.json

**DESCRIPTION**: Declare the beforeRebindTable extension function for the target table in your controlConfiguration so SAP Fiori elements will call your controller extension before the table is rebound.

**LANGUAGE**: JSON

**CODE**:
```json
"controlConfiguration": {
    _Child/@com.sap.vocabularies.UI.v1.LineItem: {
        "tableSettings": {
            "beforeRebindTable": ".extension.sap.fe.core.fpmExplorer.OPExtend.onTableRefresh"
        }
    }
}
```

**STEP**: 2. Register your controller extension in manifest.json

**DESCRIPTION**: Configure sap.ui5 -> extends -> controllerExtensions to point the framework to your controller extension implementation.

**LANGUAGE**: JSON

**CODE**:
```
"sap.ui5": {
    "extends": {
        "extensions": {
            "sap.ui.controllerExtensions": {
                "sap.fe.templates.ObjectPage.ObjectPageController": {
                    "controllerName": "sap.fe.core.fpmExplorer.OPExtend"
                }
            }
        }
    }
}
```

**STEP**: 3. Implement the beforeRebindTable handler in the controller extension

**DESCRIPTION**: Implement the onTableRefresh handler in your controller extension. Obtain the CollectionBindingInfo API from the event, then add filters, sorters, and additional select properties using collectionBindingInfoAPI.addFilter/addSorter/addSelect. The sample below shows adding a boolean filter, a sorter on "ID", and selecting "TagStatus".

**LANGUAGE**: JavaScript

**CODE**:
```javascript
sap.ui.define(
    ["sap/ui/core/mvc/ControllerExtension", "sap/ui/model/Filter", "sap/ui/model/FilterOperator"],
    function (ControllerExtension, Filter, FilterOperator) {
        "use strict";

        return ControllerExtension.extend("sap.fe.core.fpmExplorer.OPExtend", {
            onTableRefresh: function (event) {
                var collectionBindingInfoAPI = event.getParameters("collectionBindingInfo");

                //Add a filter
                var filter = new Filter({
                    path: "BooleanProperty",
                    operator: FilterOperator.EQ,
                    value1: false
                });
                collectionBindingInfoAPI.addFilter(filter);

                //Add a sorter
                var sorter = new Sorter("ID", true);
                collectionBindingInfoAPI.addSorter(sorter);

                //Request an additional property to the request
                collectionBindingInfoAPI.addSelect(["TagStatus"]);                                             }
            });
    }
);
```

**STEP**: 4. Configure beforeRebindTable for retrieving row count

**DESCRIPTION**: Point the table's beforeRebindTable to a handler that will attach to collectionBindingInfo events (dataReceived and refresh) to read getCount() and update another UI control (for example, a numeric tile or data field).

**LANGUAGE**: JSON

**CODE**:
```
"controlConfiguration": {
    "@com.sap.vocabularies.UI.v1.LineItem": {
        "tableSettings": {
            "beforeRebindTable": ".extension.sap.fe.core.fpmExplorer.customListReportHeaderContent.LRExtend.beforeRebindTableLR"
        }
    }
},
```

**STEP**: 5. Implement the beforeRebindTable handler to get table row count and update UI

**DESCRIPTION**: Use collectionBindingInfoAPI.attachEvent for "dataReceived" and "refresh". In the callbacks, call getCount() on the table instance and set the value of a target control (example uses IDs shown in manifest snippet). This ensures the UI reflects the currently loaded row count.

**LANGUAGE**: JavaScript

**CODE**:
```
beforeRebindTableLR: function (event) {
     let collectionBindingInfoAPI = event.getParameter("collectionBindingInfo");
     collectionBindingInfoAPI.attachEvent(
         "dataReceived",
         () => {
             let tableCount = this.getView()
                .byId("sap.fe.core.fpmExplorer.customListReportHeaderContent::Default--fe::table::RootEntity::LineItem::Table")
                .getCount();
             this.getView().byId("sap.fe.core.fpmExplorer.customListReportHeaderContent::Default--numericId").setValue(tableCount);
         },
         this
     );
     collectionBindingInfoAPI.attachEvent(
         "refresh",
         () => {
             let tableCount = this.getView()
                .byId("sap.fe.core.fpmExplorer.customListReportHeaderContent::Default--fe::table::RootEntity::LineItem::Table")
                .getCount();
             this.getView().byId("sap.fe.core.fpmExplorer.customListReportHeaderContent::Default--numericId").setValue(tableCount);
         },
         this
     );
}
```

fiori-elements odata-v4 beforeRebindTable table controller-extension ui5 collectionBindingInfo getCount


**TITLE**: Initial Expansion Level for Tables in List Reports & Analytical List Pages

**INTRODUCTION**: Configure the number of expanded grouping levels for tables in Fiori elements List Reports and Analytical List Pages by setting the InitialExpansionLevel on the UI.PresentationVariant annotation. Applicable to SAP Fiori elements for OData V2 only. Ensure PresentationVariant annotations exist and are referenced correctly (direct or via SelectionPresentationVariant qualifiers) for the content area or tabs.

**TAGS**: fiori-elements-framework, PresentationVariant, SelectionPresentationVariant, initialExpansionLevel, annotations, OData V2, ListReport, AnalyticalListPage, tables

STEP: 1 — Expected behavior per table type

DESCRIPTION: Know the default and enforced behavior per table type and the rule that InitialExpansionLevel must not exceed the number of grouped columns. Use this to decide which value to set.

LANGUAGE: Text

CODE:
```Text
- Analytical Table: default initialExpansionLevel is 0.
- Responsive Table: expands to one level regardless of initialExpansionLevel; groups are always expanded; grouping controlled via table settings.
- Tree Table:
  - List Reports: first level is automatically expanded.
  - Analytical List Pages: default initialExpansionLevel is 0.

Rule: initialExpansionLevel must never exceed the number of grouped columns.
```

STEP: 2 — Preconditions and association rules for PresentationVariant

DESCRIPTION: Ensure PresentationVariant annotations exist for the content area in Analytical List Pages / List Reports and for multiple tabs in List Reports. If tabs are not defined, the default (unqualified) PresentationVariant is used. Content areas can be associated directly with a PresentationVariant when:
- The manifest qualifier is defined and there is no matching SelectionPresentationVariant but a matching PresentationVariant exists.
- The manifest qualifier is not defined and there is no default SelectionPresentationVariant but a default PresentationVariant exists.
For List Report tabs, the annotation path in the manifest can point directly to a PresentationVariant annotation.

LANGUAGE: Text

CODE:
```Text
Preconditions:
- PresentationVariant must be defined for the content area or tab (qualified or default).
- If using SelectionPresentationVariant that references a PresentationVariant, the PresentationVariant must be referenced by path (not inline) — see later step.

Manifest/tab rules:
- If tab annotation path points to a PresentationVariant, define the PresentationVariant as a separate annotation with the appropriate qualifier.
```

STEP: 3 — PresentationVariant sample: XML Annotation

DESCRIPTION: Use this XML PresentationVariant sample to set InitialExpansionLevel and related grouping/sort order. Use the Qualifier as required (e.g., "Default") and reference it from the manifest or SelectionPresentationVariant.

LANGUAGE: XML

CODE:
```xml
<Annotation Term="UI.PresentationVariant" Qualifier="Default">
    <Record>
        <PropertyValue Property="Visualizations">
            <Collection>
                <AnnotationPath>@UI.LineItem#DefaultLineItem</AnnotationPath>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="GroupBy">
            <Collection>
                <PropertyPath>ProductId</PropertyPath>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="InitialExpansionLevel" Int="1"/>
        <PropertyValue Property="SortOrder">
            <Collection>
                <Record>
                    <PropertyValue Property="Property" PropertyPath="ProductCategory" />
                    <PropertyValue Property="Descending" Bool="false" />
                </Record>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

STEP: 4 — PresentationVariant sample: ABAP CDS Annotation

DESCRIPTION: Use this ABAP CDS presentationVariant example to set initialExpansionLevel and related properties. Apply the annotation to the CDS view and ensure qualifier matches manifest or tab configuration.

LANGUAGE: ABAP CDS

CODE:
```
@UI.presentationVariant: [
  {
    visualizations: [
      {
        type: #AS_LINEITEM,
        qualifier: 'DefaultLineItem'
      }
    ],
    groupBy: [
      'PRODUCTID'
    ],
    initialExpansionLevel: 1,
    sortOrder: [
      {
        by: 'PRODUCTCATEGORY',
        direction: #ASC
      }
    ],
    qualifier: 'Default'
  }
]
annotate view STTA_C_MP_Product with {
}
```

STEP: 5 — PresentationVariant sample: CAP CDS Annotation

DESCRIPTION: Use this CAP CDS format to define a PresentationVariant with InitialExpansionLevel. Ensure the named PresentationVariant (#Default) is referenced appropriately.

LANGUAGE: CDS

CODE:
```
UI.PresentationVariant #Default : {
    Visualizations : [
        '@UI.LineItem#DefaultLineItem',
    ],
    GroupBy : [
        ProductId
    ],
    InitialExpansionLevel : 1,
    SortOrder : [
        {
            Property : ProductCategory,
            Descending : false
        }
    ]
}
```

STEP: 6 — When using SelectionPresentationVariant: reference PresentationVariant by path

DESCRIPTION: If the content area or a tab uses UI.SelectionPresentationVariant that references a PresentationVariant, do not define the PresentationVariant inline. Reference the PresentationVariant using a path. Below are XML, ABAP CDS, and CAP CDS examples showing how to reference an external PresentationVariant by qualifier/path.

LANGUAGE: XML

CODE:
```xml
<Annotation Term="UI.SelectionPresentationVariant" Qualifier="MainContent">
    <Record>
        <PropertyValue Property="ID" String=""/>
        <PropertyValue Property="Text" String=""/>
        <PropertyValue Property="SelectionVariant" Path="@UI.SelectionVariant#Default"/>
        <PropertyValue Property="PresentationVariant" Path="@UI.PresentationVariant#Default"/>
    </Record>
</Annotation>
```

LANGUAGE: ABAP CDS

CODE:
```
@UI.selectionPresentationVariant: [{
  id: '',
  text: '',
  selectionVariantQualifier: 'Default',
  presentationVariantQualifier: 'Default',
  qualifier: 'MainContent'
}]
```

LANGUAGE: CDS

CODE:
```
UI.SelectionPresentationVariant #MainContent : {
    ID : '',
    Text : '',
    SelectionVariant : ![@UI.SelectionVariant#Default],
    PresentationVariant : ![@UI.PresentationVariant#Default]
},
```

STEP: 7 — Related links and references

DESCRIPTION: Quick links to related documentation for table configuration, table-only view, and default settings. Use these when implementing or verifying annotation behavior.

LANGUAGE: Text

CODE:
```Text
Related Information:
- Configuring Tables: configuring-tables-f4eb70f.md
- Configuring the Table-Only View as the Default Option: configuring-the-table-only-view-as-the-default-option-d074e26.md
- Configuring Default Settings (Visualizations, Sort Order, Filter Values): configuring-default-settings-visualizations-sort-order-filter-values-49a6ba5.md
```

fiori-elements-framework
PresentationVariant
SelectionPresentationVariant
initialExpansionLevel
annotations
OData V2
ListReport
AnalyticalListPage
tables


**TITLE**: Inline Edit — Enable and Configure Inline Editing in SAP Fiori elements (OData V4)

**INTRODUCTION**: Practical guide for enabling and configuring inline edit for List Report and Object Page SAP Fiori elements applications (OData V4). Includes UI behavior, restrictions, manifest configuration examples, connected-field rules, error handling, action/navigation behavior, and back-end requirements.

**TAGS**: fiori-elements, inline-edit, manifest.json, ListReport, ObjectPage, OData V4, connectedFields, disabledFields, enabledFields, CAP, ABAP

STEP: 1 — Purpose and scope

DESCRIPTION: Use inline edit to edit single fields or groups of fields in the active entity without creating a draft. Applicable only for SAP Fiori elements for OData V4 and supported from SAPUI5 1.136. Supported on pages based on sap.fe.templates.ListReport and sap.fe.templates.ObjectPage, and on building blocks used within these templates.

LANGUAGE: Text

CODE:
```Text
Purpose: Edit specific fields/field groups directly in active version (no draft created).
Scope: SAP Fiori elements for OData V4; templates: sap.fe.templates.ListReport, sap.fe.templates.ObjectPage.
SAPUI5 requirement: 1.136+
```

STEP: 2 — Restrictions and unsupported cases

DESCRIPTION: Inline edit is not available in certain scenarios. Validate these before enabling inline edit.

LANGUAGE: Text

CODE:
```Text
Restrictions:
- Not supported when Collaborative Draft is enabled.
- Not supported when using Flexible Column Layout.
- Not supported for stream property fields.
- Not supported for multi-input fields.
- If object already has a draft, inline edit is unavailable.
- Double-click activation is not supported on responsive tables.
```

STEP: 3 — Inline edit UI behavior and keyboard interactions

DESCRIPTION: Visual indicators, activation actions, and save/cancel interactions to implement or validate in UI. Reference images included in original docs for visual guidance.

LANGUAGE: Text

CODE:
```Text
UI indicators:
- Editable fields are underlined on hover and show an Edit (pencil) icon.
- Images (relative paths):
  - images/Inline_Edit_Indicators_5dec6b1.png
  - images/Inline_Editing_a_Field_24c44a4.png
  - images/Inline_Editing_a_Field_Group_644bea3.png

Activation:
- Click Edit icon, OR double-click field (not on responsive tables), OR press Enter when field has focus.

Save / Cancel:
- Save: click Save (check) icon or press Enter.
- Cancel: click Cancel (x) icon or press Esc.

Behavior:
- Editing updates the active version of the object directly (PATCH); no draft created.
- For connected field groups, changes across the group are submitted in a single request.
- Inline edit supports standard input types: value help, date/time pickers, RU values, etc.
```

STEP: 4 — Error management during inline edit

DESCRIPTION: How errors are surfaced and how users can fix them via inline edit. Explain limitations when error references off-page fields.

LANGUAGE: Text

CODE:
```Text
Error handling:
- On submit error, show message button in page footer.
- Fields related to the error are opened in edit mode so user can correct them.
- If a related field belongs to a connected field group, the entire group is opened for edit.
- If the error references a field not displayed on the page, inline edit cannot fix it; user must switch to full edit mode.

Reference image:
- images/Error_Caused_by_Inline_Editing_43ead48.png
```

STEP: 5 — Action execution and navigation during inline edit

DESCRIPTION: Behavior when triggering actions or navigation while inline edit changes are in progress. Include caution for external navigation.

LANGUAGE: Text

CODE:
```Text
Action / Navigation handling:
- Triggering an action or navigation from a table prompts user to Save or Discard ongoing inline edit change.
- After user chooses, the action executes or navigation proceeds.
Caution:
- Navigation triggered from browser navigation icons, FLP header, or intent-based navigation will occur and any inline edit changes will be lost.
Reference image:
- images/Prompt_to_Save_or_Discard_Changes_Navigation_a6b0edd.png
```

STEP: 6 — Manifest configuration overview

DESCRIPTION: Inline edit must be enabled at the page (component) level in manifest.json. Use inlineEdit settings with parameters: enabledFields, disabledFields, connectedFields. Parameter rules and behavior are described here.

LANGUAGE: Text

CODE:
```Text
Manifest settings (high-level):
- inlineEdit: {
    "enabledFields": [<property names or FieldGroup annotation references>],
    "disabledFields": [<property names or FieldGroup annotation references>],
    "connectedFields": [<arrays of property names or FieldGroup annotation references>]
  }

Rules:
- If disabledFields is an empty array ( [] ), inline edit is enabled for all fields.
- Use property names (e.g., BeginDate) or UI FieldGroup annotation references (e.g., @com.sap.vocabularies.UI.v1.FieldGroup#TripData).
- connectedFields groups fields that must be edited together and submitted as a single request.
Tip:
- Immediate side effects are NOT supported for source/target properties that are in the same connectedFields group (the side effect will not be triggered).
```

STEP: 7 — Example 1: Enable inline edit for all fields in List Report

DESCRIPTION: manifest.json configuration to enable inline edit for all fields by setting disabledFields to an empty array. Use this for list reports where inline edit should be globally available.

LANGUAGE: JSON

CODE:
```JSON
"TravelList": {
    "type": "Component",
    "name": "sap.fe.templates.ListReport",
    "id": "TravelList",
    "options": {
        "settings": {
            "inlineEdit": {
                "disabledFields": []
            },
            "contextPath": "/Travel",
            "initialLoad": "Enabled",
            "navigation": {
                "Travel": {
                    "detail": {
                        "route": "TravelObjectPage"
                    }
                }
            }
        }
    }
}
```

STEP: 8 — Example 2: Enable a subset of fields and define connected fields

DESCRIPTION: manifest.json configuration enabling specific fields and defining a connected field group (BeginDate & EndDate) to be edited together. Use property names in enabledFields and nested arrays in connectedFields.

LANGUAGE: JSON

CODE:
```JSON
"TravelList": {
    "type": "Component",
    "name": "sap.fe.templates.ListReport",
    "id": "TravelList",
    "options": {
        "settings": {
            "inlineEdit": {
                "enabledFields": ["to_Customer_CustomerID", "BeginDate","EndDate", "BookingFee"],
                "connectedFields": [["BeginDate", "EndDate"]]
            },
            "contextPath": "/Travel",
            "initialLoad": "Enabled",
            "navigation": {
                "Travel": {
                    "detail": {
                        "route": "TravelObjectPage"
                    }
                }
            }
        }
    }
}
```

STEP: 9 — Example 3: Enable fields using FieldGroup annotations and mixed connectedFields

DESCRIPTION: manifest.json for an Object Page where enabledFields references UI FieldGroup annotations and an OData navigation property field group. connectedFields mixes arrays of property names and a FieldGroup annotation reference.

LANGUAGE: JSON

CODE:
```JSON
"TravelObjectPage": {
    "type": "Component",
    "id": "TravelObjectPage",
    "name": "sap.fe.templates.ObjectPage",
    "options": {
        "settings": {
            "entitySet": "Travel",
            "inlineEdit": {
               "enabledFields": ["@com.sap.vocabularies.UI.v1.FieldGroup#TripData", "to_Booking/@com.sap.vocabularies.UI.v1.FieldGroup#Flight"],
                "connectedFields": [
                    ["BeginDate", "EndDate"],
                    "to_Booking/@com.sap.vocabularies.UI.v1.FieldGroup#Flight"
                ]
            }
        }
    }
}
```

STEP: 10 — Back-end configuration and behavior

DESCRIPTION: Inline edit issues direct PATCH to active entity (bypass draft). Ensure back-end supports direct updates and, for CAP, bypass-draft settings.

LANGUAGE: Text

CODE:
```Text
Back-end behavior:
- Inline edit patches the active version directly (no draft created).
ABAP:
- Follow ABAP RAP implementation recommendations for business objects.
- Reference: https://help.sap.com/docs/abap-cloud/abap-rap/abap-restful-application-programming-model

CAP Node.js:
- Ensure bypass draft option is configured correctly.
- Reference: https://cap.cloud.sap/docs/node.js/fiori#bypassing-the-sap-fiori-draft-flow

CAP Java:
- Ensure bypass draft option is configured correctly.
- Reference: https://cap.cloud.sap/docs/java/fiori-drafts#bypassing-draft-flow
```

fiori-elements
inline-edit
manifest.json
ListReport
ObjectPage
OData V4
connectedFields
disabledFields
enabledFields
CAP
ABAP


**TITLE**: Input Assistance (SAP Fiori elements for OData V4) — Implementation & Code Examples

**INTRODUCTION**: This document provides actionable steps and exact code examples for enabling, modeling, disabling, and handling input assistance (recommendations) in SAP Fiori elements applications using OData V4. Use these steps to model backend annotations, trigger recommendation updates, disable recommendations in the front end, and implement the onBeforeAcceptRecommendations hook to filter unaccepted recommendations.

**TAGS**: fiori-elements, OData V4, UI.Recommendations, input-assistance, annotations, side-effects, metadata, recommendations

STEP: 1 — Applicability, Notes, and Restrictions

DESCRIPTION:
- Input Assistance applies to SAP Fiori elements for OData V4 only.
- In edit mode, fields can show recommendations in a "Recommendations" section. One recommendation can be marked as suggestion and shown as a styled placeholder.
- If a field has a ValueState from backend messages, the recommendation placeholder is suppressed and backend messages are shown instead.
- Do not provide input assistance for fields with business-defined values or user-defined values (empty fields are an exception only when empty is valid).
- Avoid hiding recommendation fields (or their containers) in UI adaptation mode.
- Restrictions (recommendations are NOT available for):
  - Fields without value help (except fields with a drop-down list).
  - Fields with business-defined values (side effects).
  - Fields with multiple values.
  - Custom fields.
  - Fields whose value help entity has more than one key field.

LANGUAGE: Text

CODE:
```Text
Notes and restrictions summarized:
- Applies: SAP Fiori elements for OData V4 only.
- Recommendation placeholder suppressed when ValueState exists.
- Not supported: fields without value help (except dropdown), business-defined fields, multi-value fields, custom fields, fields whose value-help entity has >1 key.
```

STEP: 2 — Model UI.Recommendations at Entity Level (Required Backend Metadata)

DESCRIPTION:
- Add UI.Recommendations annotation at the entity level to point to a complex property (example: SAP_Recommendations).
- The complex property (SAP_Recommendations) must be defined on the entity and reference a complex type that lists recommendation-relevant properties.
- For each recommendation-relevant property, define a collection complex type describing incoming recommendation values (RecommendedFieldValue, RecommendedFieldDescription, RecommendedFieldScoreValue, RecommendedFieldIsSuggestion).
- Ensure the complex types match the backend implementation exactly so the Fiori elements framework reads recommendations properly.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="com.c_salesordermanage_sd.SalesOrderManage">
    <Annotation Term="UI.Recommendations" Path="SAP_Recommendations" />
</Annotations>
```

STEP: 3 — Add Complex Property on Entity for Recommendations

DESCRIPTION:
- Add a property on the EntityType that points to the complex type used to hold recommendations (property name in examples: SAP_Recommendations).
- Keep the sample EntityType structure intact and ensure types and property names match runtime metadata.

LANGUAGE: XML

CODE:
```xml
<EntityType Name="SalesOrderManage">
    <Key>
        <PropertyRef Name="ID"/>
    </Key>
    <Property Name="ID" Type="Edm.Guid" Nullable="false"/>
    <Property Name="ShippingCondition" Type="Edm.String" MaxLength="2"/>
    <NavigationProperty Name="_ShipToParty" Type="com.c_salesordermanage_sd.HeaderShipToParty" />
    <Property Name="SAP_Recommendations" Type="com.c_salesordermanage_sd.c_salesordermanage_sd_SalesOrderRecommendations"/> // This is for the recommendations
</EntityType>
```

STEP: 4 — Define Complex Type Listing Recommendation-Relevant Properties

DESCRIPTION:
- Define a complex type that lists properties of the entity that can receive recommendations. Each listed property is typed as a Collection of a recommendation-type complex type.

LANGUAGE: XML

CODE:
```xml
// SalesOrderManage entity
<ComplexType Name="c_salesordermanage_sd_SalesOrderRecommendations">
    <Property Name="ShippingCondition" Type="Collection(com.c_salesordermanage_sd.c_salesordermanage_sd_ShippingConditionRecommendationType)" Nullable="false"/>
    <Property Name="ShipToParty" Type="Collection(com.c_salesordermanage_sd.c_salesordermanage_sd_ShipToPartyRecommendationType)" Nullable="false"/>
</ComplexType>
```

STEP: 5 — Define Recommendation Complex Types (Structure of Incoming Recommendations)

DESCRIPTION:
- For each recommendation-relevant field, define a complex type with the following properties:
  - RecommendedFieldValue: recommended value (Edm.* type)
  - RecommendedFieldDescription: display text for suggestion values
  - RecommendedFieldScoreValue: confidence score (not used by frontend)
  - RecommendedFieldIsSuggestion: boolean, true => displayed as placeholder styled suggestion
- Match MaxLength/Type/Scale to backend implementation.

LANGUAGE: XML

CODE:
```xml
<ComplexType Name="c_salesordermanage_sd_ShippingConditionRecommendationType">
    <Property Name="RecommendedFieldValue" Type="Edm.String" MaxLength="2"/>
    <Property Name="RecommendedFieldDescription" Type="Edm.String" MaxLength="20"/>
    <Property Name="RecommendedFieldScoreValue" Type="Edm.Decimal" Scale="variable"/>
    <Property Name="RecommendedFieldIsSuggestion" Type="Edm.Boolean"/>
</ComplexType>
<ComplexType Name="c_salesordermanage_sd_ShipToPartyRecommendationType">
    <Property Name="RecommendedFieldValue" Type="Edm.String" MaxLength="10"/>
    <Property Name="RecommendedFieldDescription" Type="Edm.String" MaxLength="90"/>
    <Property Name="RecommendedFieldScoreValue" Type="Edm.Decimal" Scale="variable"/>
    <Property Name="RecommendedFieldIsSuggestion" Type="Edm.Boolean"/>
</ComplexType>
```

STEP: 6 — Recommendation Field Property Meanings (Reference)

DESCRIPTION:
- Use the following properties in recommendation complex types:
  - RecommendedFieldValue: The recommended value.
  - RecommendedFieldDescription: Text description (only used when RecommendedFieldIsSuggestion=true).
  - RecommendedFieldScoreValue: Confidence score (not used by Fiori client).
  - RecommendedFieldIsSuggestion: Set true for the most fitting recommendation — displayed as placeholder suggestion.

LANGUAGE: Text

CODE:
```Text
Property descriptions:
- RecommendedFieldValue: recommended value
- RecommendedFieldDescription: description for display when IsSuggestion=true
- RecommendedFieldScoreValue: confidence score (not used by frontend)
- RecommendedFieldIsSuggestion: when true -> shown as placeholder suggestion
```

STEP: 7 — Ensure Consistent Labels for Recommended Fields

DESCRIPTION:
- When unaccepted recommendations dialog appears at save, the dialog uses the property-level label for the recommended field.
- If a UI.DataField wraps the property, the object page label may differ (comes from UI.DataField). For consistent naming, ensure the property-level label equals the UI.DataField label for recommended fields.
- Dialog groups recommendations under the entity using UI.HeaderInfo.TypeName. This group name may differ from the page field group label (UI.ReferenceFacet label).

LANGUAGE: Text

CODE:
```Text
Action items:
- Ensure property-level label = UI.DataField label for recommended fields.
- Verify UI.HeaderInfo.TypeName for correct grouping in the Unaccepted Recommendations dialog.
```

STEP: 8 — Disable Input Assistance from Front End (Feature Toggle)

DESCRIPTION:
- If metadata contains recommendation annotations but you want to disable recommendation UI and behavior, call initializeFeatureToggles() and changePageConfiguration() in your AppComponent to switch off the feature.

LANGUAGE: JavaScript

CODE:
```javascript
sap.ui.define(["sap/fe/core/AppComponent"], function (AppComponent) {
    "use strict";
    return AppComponent.extend("recommendation-disableInputAssistance.Component", {
        ...
        initializeFeatureToggles: function () {
            this.changePageConfiguration("sap.fe", "app/disableInputAssistance", true);
        }
    });
});
```

STEP: 9 — Triggers for Recommendation Calls (When Backend Is Called)

DESCRIPTION:
- Recommendations are requested when:
  - A new context is created/loaded (Create in list report or new inline table row).
  - Draft version of object is loaded (Edit).
  - A draft is restored or page refreshed/back navigation restores draft.
  - Scrolling loads more content (sections/tabs/tables).
  - A configured field value changes (field triggers recommendation update).
- Use side-effects to trigger recommendation fetches from backend when a field or action changes.

LANGUAGE: Text

CODE:
```Text
Recommendation triggers:
- On create/new row, on edit/load draft, app state restore, scroll-loading of content, and on configured field change.
- Use Common.SideEffects annotation to fetch recommendation complex property.
```

STEP: 10 — Use Side Effects to Fetch Recommendations (Sample Annotation)

DESCRIPTION:
- Model a Common.SideEffects record with SourceProperties and TargetProperties. Include the SAP_Recommendations property in TargetProperties to fetch recommendations for all recommendation-relevant fields on that entity when the side effect is fired.
- When a configured source property changes, the backend must return updated recommendations in the SAP_Recommendations complex property for the entity.

LANGUAGE: XML

CODE:
```xml
<Annotation Term="Common.SideEffects" Qualifier="SoldToChangeSalesAreaShipTo">
    <Record Type="Common.SideEffectsType">
        <PropertyValue Property="SourceProperties">
            <Collection>
                <PropertyPath>SoldToParty</PropertyPath>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="TargetProperties">
            <Collection>
                <String>DistributionChannel</String>
                <String>OrganizationDivision</String>
                <String>TotalNetAmount</String>
                <String>SAP_Recommendations</String> // This brings in recommendations for all recommendation-relevant properties in this entity
                <String>_ShipToParty/*</String>
           </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

STEP: 11 — User Notifications & Unaccepted Recommendations Dialog

DESCRIPTION:
- If user tries to Save/Create while unaccepted recommendations exist (recommendation not accepted and no alternate value entered), display an "Unaccepted Recommendations" dialog listing fields and recommended values.
- The dialog allows accept/reject all or return to edit and handle individually.
- If navigating away from a draft that contains unaccepted recommendations, the standard confirm dialog appears first; if user proceeds to Save/Create, show Unaccepted Recommendations dialog next.
- Rejected recommendations in the same editing session are not shown again unless the context changes or new recommendations are fetched.

LANGUAGE: Text

CODE:
```Text
Behavior summary:
- Unaccepted recommendations => dialog at Save/Create.
- Allows accept/reject all or individual acceptance on page.
- Rejected recommendations are suppressed for the same session until context change.
```

STEP: 12 — Recommendations for Fields Not in Current View & Hook to Filter Backend Values

DESCRIPTION:
- Recommendations are fetched for fields not visible in current view (hidden personalization, unloaded sections). These appear in the Unaccepted Recommendations dialog.
- It is the application's responsibility (backend or onBeforeAcceptRecommendations hook) to ensure recommendations returned are only for fields with non-empty backend values.
- Implement the onBeforeAcceptRecommendations application hook to inspect and filter recommendationData before the dialog processes them. Remove entries that already have a non-empty value in the backend.

LANGUAGE: JavaScript / TypeScript

CODE:
```javascript
sap.ui.define(["sap/ui/core/mvc/ControllerExtension"], function (ControllerExtension) {
    "use strict";

    return ControllerExtension.extend("recommendation-basic.ext.OPExtend", {
        override: {
            recommendations: {
                onBeforeAcceptRecommendations: async function (params) {
                 // Add application logic here to ensure that from the given context (params), recommendations
                 // are returned ONLY for fields that do not have a non-empty value in the back end;
                 // remove fields with a non-empty value in back end from the recommendationData structure here.
                  params.recommendationData = returnRecommendationData;
                  return;
                },
        ...
    }
}
```

LANGUAGE: TypeScript

CODE:
```typescript
export type RecommendationData = {
    context?: ODataV4Context;
    contextIdentifier?: string[];
    contextIdentifierText?: string[];
    propertyPath?: string;
    value?: string;
    text?: string;
}
```

fiori-elements
OData V4
UI.Recommendations
input-assistance
annotations
side-effects
metadata
recommendations


**TITLE**: Interacting with a Generated Table (Table API) in SAP Fiori elements (OData V4)

**INTRODUCTION**: Quick, actionable guide to locate and access the Table control generated by Fiori elements (annotations) so code can call the Table building block API. Includes exact ID patterns, retrieval snippets, and controller-extension tips. Applicable only to SAP Fiori elements for OData V4.

**TAGS**: fiori-elements-framework, OData V4, UI5, Table API, developer-tools, manifest.json

**STEP**: 1 — Find the Table control ID in the running app

**DESCRIPTION**: Open browser developer tools and search the DOM/UI5 control tree for the TableAPI control ID. Use the full application-scoped ID pattern shown below. The ApplicationId value is the application id from manifest.json (project root / webapp/manifest.json or equivalent). PageId is the page id. Use the entity name for list report pages or the navigation property for object/custom pages.

**LANGUAGE**: Plain text

**CODE**:
```text
"<ApplicationId>::<PageId>–fe::table::<Entity name or navigation property>::LineItem::Table"
```

**STEP**: 2 — Example full ID (concrete example)

**DESCRIPTION**: Example of how a concrete full ID can look once you replace placeholders. Note the en-dash between PageId and fe in the pattern above (as used by Fiori elements).

**LANGUAGE**: Plain text

**CODE**:
```text
"com.example.myapp::MainPage–fe::table::SalesOrder::LineItem::Table"
```

**STEP**: 3 — Short ID form usable inside controller extensions

**DESCRIPTION**: Inside controller extensions you can reference the shorter form (no application/page prefix). Use this short ID when searching in the UI5 core or from code if applicable.

**LANGUAGE**: Plain text

**CODE**:
```text
"fe::table::<Entity name or navigation property>::LineItem::Table"
```

**STEP**: 4 — Retrieve the Table control from a running app (recommended approach)

**DESCRIPTION**: Use the full ID or short ID to retrieve the Table control via the UI5 core. This snippet gets the control and logs it so you can inspect available properties/methods. After retrieval, call any Table API properties or aggregations as required (see API reference link in step 6).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
// Replace with the full or short ID discovered in steps 1-3:
var sTableId = "<ApplicationId>::<PageId>–fe::table::<Entity name or navigation property>::LineItem::Table";

// Get the Table control from the UI5 core
var oTable = sap.ui.getCore().byId(sTableId);

// Inspect the control in the console, then call Table API methods/properties
console.log(oTable);

// Example: interact with the Table after inspection
// oTable.getBinding("items")   // inspect binding
// oTable.setBusy(true)        // if supported by the Table control
```

**STEP**: 5 — Retrieve the Table control inside a controller extension (use short form)

**DESCRIPTION**: In controller extensions you can use the short ID. Use sap.ui.getCore().byId for guaranteed lookup. Optionally use this.getView().byId if the ID is view-local.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
// Short ID inside controller extension
var sShortTableId = "fe::table::<Entity name or navigation property>::LineItem::Table";

// Prefer core lookup for the global short ID
var oTable = sap.ui.getCore().byId(sShortTableId);
console.log(oTable);

// Or attempt view-local lookup (may not resolve if global-scoped):
var oTableLocal = this.getView().byId(sShortTableId);
console.log(oTableLocal);
```

**STEP**: 6 — Use the Table API and references

**DESCRIPTION**: After you have the Table control instance (oTable), call properties, aggregations, and methods provided by the Table building block API. Inspect the retrieved object in the console to discover available members. Refer to the official API documentation and live building-block examples for the exact Table API surface and supported operations.

**LANGUAGE**: Plain text

**CODE**:
```text
API Reference: https://ui5.sap.com/#/api/sap.fe.macros.Table
Live examples (Building Blocks - Table): https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/table/tableDefault
```

**STEP**: 7 — Tips and reminders

**DESCRIPTION**:
- The pattern and method above apply only to SAP Fiori elements for OData V4.
- ApplicationId comes from manifest.json (project root / webapp/manifest.json).
- Use console.log(oTable) to inspect runtime API before calling methods.
- If control lookup returns null, verify the exact runtime ID string and that the table has been rendered.

fiori-elements-framework
OData V4
UI5
Table API
developer-tools
manifest.json


**TITLE**: Key User Capabilities — Fiori Elements Overview Page UI Adaptation

**INTRODUCTION**: This document describes the required roles and actionable steps for key users to perform UI adaptation in Fiori elements overview page applications. It lists available adaptation features, their behavior, and annotation best practices to ensure readable labels in adaptation mode.

**TAGS**: fiori-elements-framework, sapui5, flexibility, key-user, ui-adaptation, s4hana, my-home

**STEP**: 1 — Prerequisites: Required user roles

**DESCRIPTION**: Verify the key-user role is assigned for the target deployment. Use the appropriate role below depending on your environment. See SAPUI5 Flexibility documentation at ../04_Essentials/sapui5-flexibility-adapting-uis-made-easy-a8e55aa.md for additional details.

**LANGUAGE**: json

**CODE**:
```json
{
  "SAP_BTP": {
    "requiredRole": "FlexKeyUser"
  },
  "OnPremise": {
    "requiredRole": "SAP_UI_FLEX_KEY_USER"
  }
}
```

**STEP**: 2 — Enable UI adaptation mode

**DESCRIPTION**: Enter adaptation mode from the running Fiori application. This is a UI action performed by the assigned key user.

- Open the application in the browser.
- From the User Menu, choose "Adapt UI".
- Once in adaptation mode, use the adaptation toolbar/panels (e.g., Manage Cards, Edit Card, Filters, Variants).

**LANGUAGE**: plaintext

**CODE**:
```plaintext
UI action sequence:
1. Open Fiori app (Overview Page).
2. Click User Menu (top-right).
3. Select "Adapt UI".
4. Use adaptation panels: Manage Cards, Filters, Variants, etc.
```

**STEP**: 3 — Feature: Hide Card

**DESCRIPTION**: Hide a card so it is not shown on initial load. Hidden cards remain available in the Manage Cards list and can be restored by the key user.

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Action: Select card -> Choose "Hide"
Result: Card removed from initial view; appears in Manage Cards for re-add.
```

**STEP**: 4 — Feature: Add Card

**DESCRIPTION**: Add hidden/available cards back to the page from the list of available cards in Manage Cards.

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Action: Open Manage Cards -> Select available card(s) -> Choose "Add"
Result: Card placed on overview page according to available layout slots.
```

**STEP**: 5 — Feature: Edit Card

**DESCRIPTION**: Modify card properties: title, subtitle, KPI header, KPI value, description, chart type, sorting, navigation. For column charts you may configure threshold values that influence semantic coloring. You can disable adding individual cards to the "Insights" section only if card generation for Insights in My Home (SAP S/4HANA Cloud Public Edition) is enabled.

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Editable properties:
- title, subtitle
- KPI header, KPI value, description
- chart type, sorting, navigation (target)
- column chart: threshold values => semantic coloring
- Insights inclusion: toggle (only when My Home Insights generation is enabled)
```

**STEP**: 6 — Feature: Add/Delete Views (View Switch)

**DESCRIPTION**: Add or remove view switch fields to a card to present multiple views or datasets. Use the Add/Delete Views action to configure available views per card.

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Action: Edit card -> Add/Delete Views -> Configure view keys and content bindings
Result: Card displays view switch (tab/select) to toggle views.
```

**STEP**: 7 — Feature: Modify Card Size

**DESCRIPTION**: Resize cards by adjusting rows/columns span. Use the layout controls in adaptation mode to change card dimensions.

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Action: Select card -> Choose "Resize" -> Set rows/columns
Result: Card occupies configured grid cells on overview page.
```

**STEP**: 8 — Feature: Create Card

**DESCRIPTION**: Create new static cards. Supported new card types: static link list card and KPI card. Use the Create Card action in adaptation mode and provide required metadata (title, links or KPI binding).

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Create options:
- Static Link List Card: define links and labels
- KPI Card: define KPI data binding, title, description
Limitations: Only static link list and KPI cards can be created via adaptation.
```

**STEP**: 9 — Feature: Basic Card Operations (Cut/Copy/Paste/Save/Cancel/Reset/Publish)

**DESCRIPTION**: Perform general card operations available in adaptation mode: cut, copy, paste, save changes, cancel edits, reset to last saved state, and publish changes (make persistent for users).

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Operations:
- Cut/Copy/Paste: move or duplicate cards
- Save: persist current adaptation locally or as transport (if applicable)
- Cancel: discard unsaved changes
- Reset: revert to last persisted state
- Publish: make changes available to all users (when supported)
```

**STEP**: 10 — Feature: Adapt Filters

**DESCRIPTION**: Add or remove filter fields from the filter bar. Add specific values to filters. Changes can be saved to variants (new or existing).

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Action: Enter adaptation -> Open Filter Bar -> Add/Remove fields -> Optionally set default values
Save: Save current filter configuration as a variant or overwrite an existing variant
```

**STEP**: 11 — Feature: Adapt Variants

**DESCRIPTION**: Manage view variants: rename an existing view, save the current view, save current view as a new view, and manage (delete, reorder) variants.

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Actions:
- Rename variant
- Save variant (overwrite)
- Save As: create new variant from current view
- Manage: delete/reorder variants
```

**STEP**: 12 — Best Practices: Maintain property labels for annotations

**DESCRIPTION**: Ensure readable labels in UI adaptation mode by providing the recommended property labels for key annotations. This mapping helps adaptation UI display meaningful names.

**LANGUAGE**: json

**CODE**:
```json
{
  "AnnotationLabelMapping": {
    "PresentationVariant": "text",
    "SelectionVariant": "text",
    "DataPoint": "title",
    "IdentificationAnnotation": "label (based on priority in DataFieldForIntentBasedNavigation / DataFieldWithURL)",
    "chartAnnotation": "description"
  }
}
```

**STEP**: 13 — Notes and constraints

**DESCRIPTION**: Preserve these constraints when implementing or automating adaptation tasks:

- Column chart semantic coloring via threshold values applies only to column chart cards.
- Insights inclusion toggle is available only when card generation for the Insights section of My Home (SAP S/4HANA Cloud Public Edition) is enabled.
- Created cards are limited to static link list and KPI card types.
- Role names are exact and case-sensitive: "FlexKeyUser" (BTP) and "SAP_UI_FLEX_KEY_USER" (on premise).

**LANGUAGE**: plaintext

**CODE**:
```plaintext
Constraints:
- Role names: FlexKeyUser (BTP), SAP_UI_FLEX_KEY_USER (on premise)
- Column chart thresholds => semantic coloring only for column charts
- Insights toggle depends on My Home Insights generation setting
- Creation limited to static link list & KPI cards
```

fiori-elements-framework sapui5 flexibility key-user ui-adaptation s4hana my-home


**TITLE**: Key Value Facet (UI.DataPoint) — Create a key/value data point and render as ReferenceFacet

**INTRODUCTION**: Show how to define a UI.DataPoint annotation (key/value) and reference it from a UI.ReferenceFacet so the title and value are rendered as a key/value facet in SAP Fiori Elements. Includes examples for XML OData annotations, ABAP CDS, and CAP CDS, plus how to color the data point using Criticality and notes about link behavior and navigation.

**TAGS**: fiori-elements-framework, UI.DataPoint, ReferenceFacet, annotations, OData V4, ABAP CDS, CAP CDS, XML, criticality, navigation

**STEP**: 1 — Define a UI.DataPoint annotation (basic title + value)

**DESCRIPTION**: Create a UI.DataPoint annotation (qualified) that provides a Title and Value. This DataPoint can then be referenced from a UI.ReferenceFacet to render a key/value facet. The image shows how a UI.DataPoint title and value are rendered: images/Key_Value_Facet_aed9f13.jpg

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="UI.DataPoint" Qualifier="ProductCategory">
      <Record>
            <PropertyValue Property="Value" Path="ProductCategory"/>
            <PropertyValue Property="Title" String="{@i18n>ProductCategory}"/>
      </Record>
</Annotation>
```

**LANGUAGE**: ABAP CDS

**CODE**:
```abap
@UI.dataPoint: {
  title: '{@i18n>@ProductCategory}'
}
ProductCategory;
```

**LANGUAGE**: CDS

**CODE**:
```cds
UI.DataPoint #ProductCategory : {
    Value : ProductCategory,
    Title : '{@i18n>@ProductCategory}'
}
```

**STEP**: 2 — Render DataPoint as a ReferenceFacet in the UI (action)

**DESCRIPTION**: Reference the qualified UI.DataPoint from a UI.ReferenceFacet in your UI annotation manifest or OData UI annotations so the title and value are rendered as a key/value facet. (Create a UI.ReferenceFacet that targets the DataPoint qualifier created in Step 1.)

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Example: A ReferenceFacet that would reference the DataPoint qualifier -->
<!-- Ensure this is placed where facets are defined in your OData UI annotations -->
<Annotation Term="UI.Facets">
  <Collection>
    <Record Type="UI.ReferenceFacet">
      <PropertyValue Property="Target" String="UI.DataPoint#ProductCategory"/>
      <PropertyValue Property="Label" String="Product Category"/>
    </Record>
  </Collection>
</Annotation>
```

**STEP**: 3 — Color the DataPoint based on Criticality (availability example)

**DESCRIPTION**: Add a Criticality property to the UI.DataPoint to render the value with color indicating criticality. Examples for XML, ABAP CDS, and CAP CDS are provided. The Criticality property can be a path to a field that calculates criticality.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="UI.DataPoint" Qualifier="StockAvailability">
      <Record Type="UI.DataPointType">
           <PropertyValue Property="Title" String="Availability" />
           <PropertyValue Property="Value" Path="stock/availability" />
           <PropertyValue Property="Criticality" Path="stock/availability"/>
      </Record>
</Annotation>
```

**LANGUAGE**: ABAP CDS

**CODE**:
```abap
@UI.dataPoint: {
  title: 'Availability',
  criticality: 'stock/availability'
}
stock/availability;
```

**LANGUAGE**: CDS

**CODE**:
```cds
UI.DataPoint #StockAvailability : {
    Value : stock/availability,
    Title : Availability,
    Criticality : stock/availability
}
```

**STEP**: 4 — Semantic object on DataPoint value (link behavior and limitation)

**DESCRIPTION**: If you add a semantic object annotation to the DataPoint value field, the value is shown as a link but criticality styling is not shown on that linked value. Use semantic object annotations when you need outbound navigation from the value, but be aware of this limitation.

**LANGUAGE**: (documentation reference)

**CODE**:
```text
Tip: For information about adding the semantic object annotation, see:
- Using a Link section in Navigation from an App (Outbound Navigation): navigation-from-an-app-outbound-navigation-d782acf.md
```

**STEP**: 5 — Enable navigation from DataPoint title (OData V4 additional feature)

**DESCRIPTION**: For SAP Fiori Elements on OData V4, you can enable in-page and external navigation from a DataPoint title. See the Navigation from Header Facet Title documentation for details and implementation examples.

**LANGUAGE**: (documentation reference)

**CODE**:
```text
Note: You can also enable in-page and external navigation from a data point title.
See: Navigation from Header Facet Title => navigation-from-header-facet-title-fa0ca22.md
```

fiori-elements-framework
UI.DataPoint
ReferenceFacet
annotations
OData V4
ABAP CDS
CAP CDS
XML
criticality
navigation


**TITLE**: SAP Fiori Elements — Keyboard Shortcuts Reference and Manifest Configuration Examples

**INTRODUCTION**: This document provides a concise, code-focused reference of standard keyboard shortcuts in SAP Fiori elements and concrete manifest/annotation examples to (1) redirect standard shortcuts to custom actions (OData V2), (2) define new shortcuts for custom actions, and (3) assign shortcuts to annotation-based action and navigation buttons (both OData V2 and OData V4 scenarios). Use these snippets directly in manifest.json and annotation files when implementing custom keyboard behavior.

**TAGS**: fiori-elements, keyboard-shortcuts, manifest.json, annotations, odata-v2, odata-v4, sap.ui.commands, DataFieldForAction, DataFieldForIntentBasedNavigation

STEP: Standard Keyboard Shortcuts Reference

DESCRIPTION: Use this concise mapping when implementing or testing keyboard-driven behavior. The focus/prerequisite column indicates where keyboard focus must be for the shortcut to trigger. Use this reference to ensure your UI state and focus management align with shortcut behavior.

LANGUAGE: Text

CODE:
```text
Standard keyboard shortcuts (Windows / Mac) — prerequisites and result summary:

- Cancel/Discard Draft
  - Shortcut: [Esc] / [Esc]
  - Prerequisite: Focus anywhere on the object page in edit mode.
  - Floorplan: Object page
  - Result: Same as clicking Cancel (non-draft) or Discard Draft (draft apps).

- Create
  - Shortcut: Ctrl + Enter / Cmd + Enter
  - Prerequisite: Focus on the table.
  - Floorplans: List report, Object page
  - Result: Same as choosing Create.

- Create with filters (not applicable to OData V4)
  - Shortcut: Shift + Ctrl + Enter / Shift + Cmd + Enter
  - Prerequisite: Focus on the table.
  - Floorplan: List report
  - Result: Same as Create With Filters.

- Delete (page level)
  - Shortcut: Ctrl + Del / Cmd + fn + delete (use ← if no delete key)
  - Prerequisite: Focus anywhere on the object page in display mode.
  - Floorplan: Object page
  - Result: Same as Delete on object page.

- Delete table entry
  - Shortcut: Ctrl + D / Cmd + D
  - Prerequisite: Focus on the table.
  - Floorplans: List report, Object page
  - Result: Same as Delete in a table.
  - Note: Requires selection for multi-delete or focus for single delete. Only works on read-only/display-only content.

- Edit page level
  - Shortcut: Ctrl + E / Cmd + E
  - Prerequisite: Focus anywhere on the object page.
  - Floorplan: Object page
  - Result: Same as Edit on object page.

- Export as
  - Shortcut: Shift + Ctrl + E / Shift + Cmd + E
  - Prerequisite: Focus on the table.
  - Floorplans: Analytical list page, List report, Object page
  - Result: Same as Export to Excel > Export As.

- Go (SmartFilterBar)
  - Shortcut: Enter / Enter
  - Prerequisite: Focus on SmartFilterBar input.
  - Floorplans: Analytical list page, List report, Object page
  - Result: Triggers search in SmartFilterBar.

- Go (Visual filter) — not applicable to OData V4
  - Shortcut: Ctrl + Enter / Cmd + Enter
  - Prerequisite: Focus on visual filter panel or its elements.
  - Floorplan: Analytical list page (visual filter)
  - Result: Triggers Go in visual filter.

- Open error list
  - Shortcut: Ctrl + Shift + M / Cmd + Shift + M
  - Prerequisite: Focus anywhere on object page in edit mode.
  - Floorplan: Object page
  - Result: Same as choosing Error button.

- Save page level
  - Shortcut: Ctrl + S / Cmd + S
  - Prerequisite: Page in edit mode, focus anywhere on object page.
  - Floorplan: Object page
  - Result: Same as Save on object page.

- Select row in tables
  - Shortcut: Shift + Space / Shift + Space
  - Prerequisite: Focus on a table cell.
  - Floorplans: Analytical list page, List report, Object page
  - Result: Selects entire row.

- Share (not applicable to OData V4)
  - Shortcut: Shift + Ctrl + S / Shift + Cmd + S
  - Prerequisite: Focus anywhere on list report or object page (if on filter bar opens near Share).
  - Floorplans: Analytical list page, List report, Object page
  - Result: Opens share ActionSheet.

- Table settings
  - Shortcut: Ctrl + , / Ctrl + ,
  - Prerequisite: Focus on the table.
  - Floorplans: Analytical list page, List report, Object page
  - Result: Same as Table Settings.
```

STEP: Redirect Standard Shortcuts to Custom Actions (OData V2)

DESCRIPTION: To have standard shortcuts (Create, Delete, Edit, Save) trigger your custom action handlers, add a logicalAction property to the action definition in manifest.json for the corresponding template/page. The custom action inherits general properties and overrides the standard action (shortcut, rendering position, properties) unless explicitly defined. Ensure the standard action would be rendered normally (same prerequisites).

LANGUAGE: JSON

CODE:
```json
"sap.suite.ui.generic.template.ListReport.view.ListReport": {
    "controllerName": "STTA_SO_ND.ext.controller.ListReportExtension",
    "sap.ui.generic.app": {
        "STTA_C_SO_SalesOrder_ND": {
            "EntitySet": "STTA_C_SO_SalesOrder_ND",
            "Actions": {
                "CreateExt": {
                    "id": "CreateExt",
                    "text": "Create (Ext)",
                    "press": "onCreateWithParameters",
                    "logicalAction": "Create"
                }
            }
        }
    }
}
```

LANGUAGE: JSON

CODE:
```json
 "sap.suite.ui.generic.template.ObjectPage.view.Details": {
    "controllerName": "STTA_SO_ND.ext.controller.DetailsExtension",
    "sap.ui.generic.app": {
        "STTA_C_SO_SalesOrder_ND": {
            "EntitySet": "STTA_C_SO_SalesOrder_ND",
            "Header": {
                "Actions": {
                    " MySmartTableDelete": {
                        "id": "customdelete",
                        "text": "Custom Delete",
                        "press": "fnCustomDelete",
                        "logicalAction": "Delete"
                    }
                }
            },
            "Sections": {
                "to_Item::com.sap.vocabularies.UI.v1.LineItem": {
                    "id": "to_Item::com.sap.vocabularies.UI.v1.LineItem",
                    "Actions": {
                        "MySmartTableCreate": {
                            "id": "customcreate",
                            "text": "CustomCreate",
                            "press": " fnCustomCreate",
                            "logicalAction": "Create"
                        }
                    }
                }
            }
        }
    }
},
```

STEP: Redirect Supported Shortcuts (OData V2) — Quick Reference

DESCRIPTION: Use these logicalAction names when redirecting shortcuts in the manifest (as shown above). Confirm prerequisite/focus rules before overriding.

LANGUAGE: Text

CODE:
```text
List Report:
- logicalAction "Create"  -> Ctrl + Enter
- logicalAction "CreateWithFilters" -> Shift + Ctrl + Enter
- logicalAction "Delete" -> Ctrl + D

Object Page:
- Header:
  - "Save" -> Ctrl + S
  - "Edit" -> Ctrl + E
  - "Delete" -> Ctrl + Del
- Sections:
  - "Create" -> Ctrl + Enter
  - "Delete" -> Ctrl + D
```

STEP: Define New Keyboard Shortcuts for Custom Actions (List Report example)

DESCRIPTION: Define a sap.ui.commands command in manifest.json under sap.ui5->extends->extensions->sap.ui.commands. Reference the command from your action in the sag.ui.generic.app Actions block using the "command" property. The description property becomes the label shown in the keyboard shortcuts popup.

LANGUAGE: JSON

CODE:
```json
"extends": {
    "extensions": {
        "sap.ui.commands": {
            "sap.suite.ui.generic.template.ListReport#sap.suite.ui.generic.template.ListReport::STTA_C_MP_Product": {
                "ChangePriceCommand": {
                    "shortcut": "Ctrl+G",
                    "description": "Change Price"
                }
            },
        },
        "sap.ui.controllerExtensions": {
            "sap.suite.ui.generic.template.ListReport.view.ListReport": {
                "controllerName": "STTA_MP.ext.controller.ListReportExtension",
                "sap.ui.generic.app": {
                    "STTA_C_MP_Product": {
                        "EntitySet": "STTA_C_MP_Product",
                        "Actions": {
                            "ChangePrice": {
                                "id": "ChangePrice",
                                "text": "Change price",
                                "press": "onChangePrice",
                                "command": "ChangePriceCommand"
                            },
                        }
                    }
                }
            }
        }
    }
}
```

STEP: Define Custom Shortcut for DataFieldForAction (Annotation + manifest mapping)

DESCRIPTION: For DataFieldForAction (annotation-driven action), add the action annotation referencing an OData FunctionImport and map the function to a command name in manifest under sap.ui.generic.app.pages.component.settings.annotatedActions. Then define the command shortcut under sap.ui.commands in sap.ui5->extends->extensions. This connects annotation-driven actions to keyboard shortcuts.

LANGUAGE: XML

CODE:
```xml
<Record Type="UI.DataFieldForAction">
    ...
    <PropertyValue Property="Action" String="<Schema Namespace>.<EntityContainer Name>/<FunctionImport Name>" />
</Record>
```

LANGUAGE: JSON

CODE:
```json
"sap.ui5": {
    "extends": {
        "extensions": {
            "sap.ui.commands": {
                "<Component Name>#<Component ID without app ID prefix>": {
                    "<Command Name>": {
                        "shortcut": "Ctrl+B"
                    }
                }
            }
        }
    }
},
"sap.ui.generic.app": {
    "pages": {
        "ListReport|<Entity Set Name>": {
            "component": {
                "settings": {
                    "annotatedActions": {
                        "<FunctionImport Name>": {
                            "command": "<Command Name>"
                        }
                    }
                }
            }
        }
    }
}
```

STEP: Define Custom Shortcut for DataFieldForIntentBasedNavigation (Annotation + manifest mapping)

DESCRIPTION: For DataFieldForIntentBasedNavigation, ensure a matching outbound navigation exists with the same semantic object and action. Map the outbound navigation to a command name in sap.ui.generic.app.pages.component.settings.outbounds, then define the command->shortcut mapping under sap.ui.commands in sap.ui5->extends->extensions.

LANGUAGE: XML

CODE:
```xml
<Record Type="UI.DataFieldForIntentBasedNavigation">
    <PropertyValue Property="SemanticObject" String="<Semantic Object>" />
    <PropertyValue Property="Action" String="<Action>" />
</Record>
```

LANGUAGE: JSON

CODE:
```json
"sap.app": {
    "crossNavigation": {
        "inbounds": {},
        "outbounds": {
            "<Outbound Navigation Name>": {
                "semanticObject": "<Semantic Object>",
                "action": "<Action>"
            }
        }
    }
},
"sap.ui5": {
    "extends": {
        "extensions": {
            "sap.ui.commands": {
                "<Component Name>#<Component ID without app ID prefix>": {
                    "<Command Name>": {
                        "shortcut": "Ctrl+B"
                    }
                }
            }
        }
    }
},
"sap.ui.generic.app": {
    "pages": {
        "ListReport|<Entity Set Name>": {
            "component": {
                "settings": {
                    "outbounds": {
                        "<Outbound Navigation Name>": {
                            "command": "<Command Name>"
                        }
                    }
                }
            }
        }
    }
}
```

STEP: OData V4 — Default Positive Action and Command Mapping

DESCRIPTION: For OData V4 apps, Ctrl+Enter (Windows) or Cmd+Return (Mac) triggers the default positive action (page-level) if the focus isn't on a control that uses the same keys. Standard shortcut resolution favors controls closest to focus (e.g., table create). To add custom commands or map annotation-based commands to shortcuts in Fiori Elements V4, associate a "command" in annotation settings and map that command under sap.ui5 extends sap.ui.commands. For object pages, append "#<ObjectPageID>" to the component key to scope commands to an object page instance.

LANGUAGE: JSON

CODE:
```json
"@com.sap.vocabularies.UI.v1.LineItem": {
    "actions": {
        "DataFieldForAction::com.c_salesordermanage_sd.CreateWithSalesOrderType": {
            "command": "BOUND"
        }
    }
}
```

LANGUAGE: JSON

CODE:
```json
"sap.ui5": {
    "extends": {
        "extensions": {
            "sap.ui.commands": {
                "sap.fe.templates.ListReport": {
                    "BOUND": {
                        "shortcut": "Ctrl+B"
                    }
                },
                "sap.fe.templates.ObjectPage": {
                    "IBNI": {
                        "shortcut": "Ctrl+K"
                    }
                },
                "sap.fe.templates.ObjectPage#SalesOrderManageObjectPage": {
                    "IBNI": {
                        "shortcut": "Ctrl+I"
                    }
                }
            }
        }
    }
}
```

STEP: Best Practices & Restrictions (Actionable Notes)

DESCRIPTION: Use these rules when implementing shortcuts to avoid conflicts and ensure user expectations.

LANGUAGE: Text

CODE:
```text
- Do not assign a custom shortcut that conflicts with standard Fiori Elements shortcuts.
- A shortcut is invoked only when the focus is within the control that holds the button (e.g., table toolbar actions require table focus).
- Header and footer buttons are global and will trigger irrespective of keyboard focus unless overridden by a closer control.
- Inline actions and inline navigation buttons in tables do NOT support custom keyboard shortcuts.
- For object page-scoped commands, include "#<ObjectPageID>" after the component key to scope the command to that object page instance.
- Ensure that the standard action would be rendered under current app conditions before attempting to override it with logicalAction.
```


**TITLE**: Line Chart Card — Configuration Guide for Code Generation

**INTRODUCTION**: Brief, code-focused guide to implement a Line Chart Card in a Fiori Elements / UI5 card or chart component. Explains required data mapping (dimensions/measures and roles), recommended usage patterns, and enabling semantic color palette. Includes reusable JSON templates to map model properties to chart configuration.

**TAGS**: fiori-elements-framework, line-chart, chart-configuration, dimensions, measures, semantic-coloring, ui5, cards

**STEP**: 1 — Overview and requirements

**DESCRIPTION**: Summary of what a Line Chart Card displays and the minimal requirements to render it. Use this as a checklist before implementing the chart mapping.

- Line charts display information as a series of data points connected by straight-line segments.
- A line chart needs at least one measure and one dimension.
- Dimensions with role = "category" form the x-axis (category axis). If none specified, the first dimension is used.
- Dimensions with role = "series" create separate lines (different colors) per distinct series value. Multiple series-role dimensions are treated together as one composite series.
- Measures form the y-axis (value axis). Multiple measures render as multiple colored lines.
- Use time-based dimensions (day, date, quarter, year) for the category axis when visualizing trends.
- Semantic color palette is supported and can be enabled in the chart configuration.

**LANGUAGE**: Plain text

**CODE**:
```text
Checklist:
- At least 1 dimension (category)
- At least 1 measure
- Optional: 1+ series dimensions for multiple lines
- Recommended: category dimension should be time-based for trend visualization
- Optional: enable semantic color palette for coloring by value/semantic
```

**STEP**: 2 — Map dimensions and roles (JSON template)

**DESCRIPTION**: Use this JSON template to map model properties to the chart's dimensions. Assign roles explicitly: "category" for x-axis, "series" for separating lines. If you omit a category role, the chart should use the first dimension defined.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "chart": {
    "type": "Line",
    "dimensions": [
      {
        "path": "OrderDate",
        "role": "category",
        "dataType": "Date",
        "format": "yyyy-MM-dd"
      },
      {
        "path": "Region",
        "role": "series",
        "dataType": "String"
      }
    ],
    "measures": [
      {
        "path": "Revenue",
        "label": "Revenue"
      }
    ]
  }
}
```

**STEP**: 3 — Multiple measures template

**DESCRIPTION**: When multiple measures are used, each measure becomes a separate colored line. Use this JSON template to declare multiple measures. Keep dimension mapping unchanged.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "chart": {
    "type": "Line",
    "dimensions": [
      { "path": "OrderDate", "role": "category", "dataType": "Date" }
    ],
    "measures": [
      { "path": "Revenue", "label": "Revenue" },
      { "path": "Profit", "label": "Profit" },
      { "path": "Cost", "label": "Cost" }
    ]
  }
}
```

**STEP**: 4 — Composite series (multiple series dimensions)

**DESCRIPTION**: If you assign multiple dimensions the role "series", their combined values form the series key and the chart assigns a single color per combined value. Use this template to declare composite series.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "chart": {
    "type": "Line",
    "dimensions": [
      { "path": "OrderDate", "role": "category", "dataType": "Date" },
      { "path": "ProductCategory", "role": "series", "dataType": "String" },
      { "path": "SalesChannel", "role": "series", "dataType": "String" }
    ],
    "measures": [
      { "path": "Revenue", "label": "Revenue" }
    ]
  }
}
```

**STEP**: 5 — Enable semantic color palette

**DESCRIPTION**: Enable semantic coloring to map colors to semantic values (for example, good/neutral/bad). This snippet shows a generic flag and an example mapping structure. Adapt mapping keys to your charting implementation's expected properties.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "chart": {
    "type": "Line",
    "semanticColoring": true,
    "semanticPalette": {
      "Positive": "#2E7D32",
      "Neutral": "#FFC107",
      "Negative": "#D32F2F"
    },
    "dimensions": [
      { "path": "OrderDate", "role": "category" }
    ],
    "measures": [
      { "path": "Revenue" }
    ]
  }
}
```

**STEP**: 6 — Best practices and recommendations

**DESCRIPTION**: Actionable recommendations to ensure effective chart visualization and correct mapping.

- Use time-based dimensions for category axis when showing trends (day, date, quarter, year).
- Prefer a single dimension with role = "category" for clarity unless a composite category is required.
- Use role = "series" only for dimensions that should split lines; avoid unnecessary series dimensions when there are many unique values (may clutter the chart).
- When using multiple measures, ensure labels and legends are clear to distinguish lines.
- Enable semantic coloring for business-critical thresholds; otherwise use a consistent categorical palette.

**LANGUAGE**: Plain text

**CODE**:
```text
Best practices:
- Category axis: time-based dimensions recommended (day/date/quarter/year)
- Series role: use sparingly; composite series created when multiple series-role dimensions are present
- Measures: each measure becomes a separate line
- Semantic coloring: enable for value semantics (good/neutral/bad) or disable for neutral color palettes
```

fiori-elements-framework line-chart chart-configuration dimensions measures semantic-coloring ui5 cards