**TITLE**: Enable and Configure Semantic Date Operators in Filter Bar (SAP Fiori Elements)

**INTRODUCTION**: Action-oriented guide for enabling semantic date operators (semantic date ranges like TODAY, LASTWEEK) in the filter bar for SAP Fiori Elements apps. Covers OData V2 and V4: manifest settings, metadata requirements, field-level overrides, inclusion/exclusion rules, default values (including parameterized operators), custom implementations, and enabling additional operators.

**TAGS**: fiori-elements-framework, filter-bar, semantic-dates, manifest.json, OData-V2, OData-V4, CDS, XML, JSON

STEP: 1 — Enable semantic date control (OData V2)
DESCRIPTION: Ensure the entity property metadata allows interval filtering and enable useDateRange in the app manifest to render semantic date controls instead of a date picker.
LANGUAGE: XML
CODE:
```xml
<Property Name="DeliveryDate" Type="Edm.DateTime" sap:label="Delivery Date" Precision="0" sap:display-format="Date" sap:filter-restriction="interval" />
```

STEP: 2 — CDS hint for OData V2 interval filter
DESCRIPTION: For ABAP CDS or CDS-like models, mark the field as interval selection to enable semantic range usage.
LANGUAGE: CDS
CODE:
```
@Consumption.filter.selectionType: #INTERVAL
```

STEP: 3 — Enable date range globally in manifest (OData V2)
DESCRIPTION: Set useDateRange to true in the generic app filterSettings to enable semantic date ranges globally (default is false). This example enables default date ranges for all date types.
LANGUAGE: JSON
CODE:
```json
"sap.ui.generic.app": {
    "pages": {
        "ListReport|SEPMRA_C_PD_Product: {
            "component": {
                "settings" : {
                    "filterSettings": {
                        "dateSettings":{
                            "useDateRange": true //Default value of the property is false. If set to true all date types will get default date ranges.
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 4 — Customize default date range options and field overrides (OData V2)
DESCRIPTION: Override default date range options and exclude or include specific values per property by configuring selectedValues and exclude under dateSettings.fields. Use customDateRangeImplementation to supply a JS class that modifies the list.
LANGUAGE: JSON
CODE:
```json
"sap.ui.generic.app": {
   "pages": {
        "component": {
           "settings" : {
                ...
                "filterSettings": {
                    "dateSettings":{
			            "useDateRange": true,
                        "fields": {
                            "DateProperty1": {
                                //Override for a specific property of type sap:date DateProperty1. This is the most simplest way of removing selected values
                                // from the standard date range. The values which you want to remove or keep needs to be mentioned as selectedValues
                                // in a comma separated format
                                "selectedValues": "TOMORROW,NEXT,LASTYEAR,LAST2WEEKS,LAST3WEEKS,LAST4WEEKS,LAST5WEEKS,YEARTODATE,QUARTER1,QUARTER2,QUARTER3,QUARTER4",
                                //Below is an optional property. Default value "exclude" property is true. If set to false, values listed in the "selectedValues" above are shown in the drop down
                                "exclude": true
                            }
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 5 — Provide default selectedValues and field precedence (OData V2)
DESCRIPTION: Define default dateSettings.selectedValues applied globally and override per-field under fields. Field-level settings take precedence over defaults; absence of selectedValues leads to date picker rendering.
LANGUAGE: JSON
CODE:
```json
"sap.ui.generic.app": {
   "pages": {
      "component": {
         "settings" : {
            ...
            "filterSettings": {
                "dateSettings":{
                    "selectedValues": "DAYS,WEEK,MONTH,DATERANGE ",
                    "fields": {
                        "DateProperty1": {
                            "selectedValues": "TOMORROW,NEXT,LASTYEAR,LAST2WEEKS,LAST3WEEKS,LAST4WEEKS,LAST5WEEKS,YEARTODATE,QUARTER1,QUARTER2,QUARTER3,QUARTER4",
                            "exclude": true
                        },
                        "DateProperty2": {
                            "customDateRangeImplementation": "SOMULTIENTITY.ext.controller.customDateRangeType",
                            "selectedValues": "FROM,TO,DAYS,WEEK,MONTH,DATERANGE,TODAY,TOMORROW,YEAR,YESTERDAY",
                            "exclude": true
                        },
                        "DateProperty3": {
                            "selectedValues": "YESTERDAY",
                            "exclude": false
                        },
		            "DateTimeProperty1": {
                            "selectedValues": "MONTH",
                            "exclude": true
                        }

                        }
                    }
                }
            }
        }
    }
}
```

STEP: 6 — Set default semantic date values (OData V2)
DESCRIPTION: Assign default semantic date values per field via dateSettings.fields.<Property>.defaultValue.operation. The default value must be part of the allowed values for that field.
LANGUAGE: JSON
CODE:
```json
"filterSettings": {
	"dateSettings": {
		"fields": {
			"CreatedDate": {
				"defaultValue": {
					"operation": "TOMORROW"
				}
			},
			"DeliveryDate": {
				"defaultValue": {
					"operation": "TOMORROW"
				},
				"filter": [{
					"path": "key",
					"equals": "TODAY",
					"exclude": true
				}]
			}
		}
	}
}
```

STEP: 7 — Exclude specific semantic date keys using filter (OData V2)
DESCRIPTION: Use the filter array on a field to include/exclude specific keys (path: 'key'), with equals and exclude flags. This supports detailed inclusion/exclusion rules per value.
LANGUAGE: JavaScript
CODE:
```
filterSettings: {
	dateSettings: {
		useDateRange: false
		fields: {
			"PostingDate": {
				//Alternate way of configuring is using the Filter option. Here the developer should be able to specify
				// the condition specific to each and every value (whether it is a key/category), needs to be excluded
				// or included. You could also specify the operator whether it is contains or equal. This configuration
				// passed directly to the filter bar and therefore anything that is possible in SFB can be configured
				// here as well
				//Application can use this for more complex and detailed configuration
				"filter": [{
						path: 'key',
						equals: 'TODAY',
						exclude: true
					} // TODAY filter will be removed
				]
			}
		}
	}
}
```

STEP: 8 — Include/Exclude examples (OData V2)
DESCRIPTION: Include a specific key (TODAY) while excluding other keys (TODAYFROMTO) using explicit filter array entries.
LANGUAGE: JSON
CODE:
```json
"filter": [{
		"path": "key",
		"equals": "TODAY",
		"exclude": false
	},
	{
		"path": "key",
		"equals": "TODAYFROMTO",
		"exclude": true
	}
]
```

STEP: 9 — Exclude categories via DateRangeType category (OData V2)
DESCRIPTION: Exclude whole categories of date operators by filtering on path: 'category' with contains and exclude flags (e.g., remove all FIXED keys).
LANGUAGE: JSON
CODE:
```json
"filter": [{
	"path": "category",
	"contains": "FIXED",
	"exclude": true
}]
// this will remove all the keys under the category that "contains" FIXED
```

STEP: 10 — Default behavior and supported fields (OData V4)
DESCRIPTION: Semantic operators are enabled by default for Edm.Date fields with FilterRestrictions.AllowedExpressions = SingleRange or SingleValue, and for Edm.DateTimeOffset fields with AllowedExpressions = SingleRange. To enable, add FilterRestrictions annotations.
LANGUAGE: XML
CODE:
```xml
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Capabilities.V1.xml">
   <edmx:Include Namespace="Org.OData.Capabilities.V1" Alias="Capabilities" />
</edmx:Reference>
<Annotations Target="com.c_salesordermanage_sd.EntityContainer/SalesOrderManage">
    <Annotation Term="Capabilities.FilterRestrictions">
        <Record Type="Capabilities.FilterRestrictionsType">
            <PropertyValue Property="FilterExpressionRestrictions">
                <Collection>
                    <Record Type="Capabilities.FilterExpressionRestrictionType">
                        <PropertyValueProperty="Property"PropertyPath="myDate"/>
                        <PropertyValueProperty="AllowedExpressions"String="SingleRange"/>
                    </Record>
                    …
                    …
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
    …
    …
</Annotations>
```

STEP: 11 — CAP CDS FilterRestrictions sample (OData V4)
DESCRIPTION: Use CAP CDS annotations to set FilterRestrictions.AllowedExpressions = 'SingleRange' for a date property.
LANGUAGE: CDS
CODE:
```
@Capabilities : {
   FilterRestrictions : {
      FilterExpressionRestrictions :
         [{
            Property : 'myDate',
            AllowedExpressions : 'SingleRange'
         }]
      }
}
...
entity MyEntity {
...
    myDate: Date;
}
```

STEP: 12 — Set default operator value in manifest (OData V4)
DESCRIPTION: Set default semantic operator for a filter field via controlConfiguration / SelectionFields / filterFields.<Field>.settings.defaultValues with operator string.
LANGUAGE: JSON
CODE:
```json
"settings" : {
   "contextPath" : "/SalesOrderManage",
   "controlConfiguration" : {
      "@com.sap.vocabularies.UI.v1.SelectionFields" : {
   …
   …
         "filterFields": {
            "SalesOrderDate": {
               "settings": {
                  "defaultValues": [{"operator": "YESTERDAY"}]
               }
            }
         }
   …
   …
      }
   }
}
```

STEP: 13 — Supported semantic operators (OData V4)
DESCRIPTION: Complete list of fully supported single-date and date-range operators; use these as values for default operator or for inclusion/exclusion rules.
LANGUAGE: JSON
CODE:
```json
{
  "singleDateOperators": ["YESTERDAY","TOMORROW","TODAY","FIRSTDAYWEEK","LASTDAYWEEK","FIRSTDAYMONTH","LASTDAYMONTH","FIRSTDAYQUARTER","LASTDAYQUARTER","FIRSTDAYYEAR","LASTDAYYEAR"],
  "dateRangeOperators": ["THISWEEK","LASTWEEK","NEXTWEEK","THISMONTH","LASTMONTH","NEXTMONTH","THISQUARTER","LASTQUARTER","NEXTQUARTER","QUARTER1","QUARTER2","QUARTER3","QUARTER4","THISYEAR","LASTYEAR","NEXTYEAR","YEARTODATE","DATETOYEAR","Empty"]
}
```

STEP: 14 — Default values for operators that require parameters — DATE/FROM/TO/DATERANGE (OData V4)
DESCRIPTION: Examples for manifest defaultValues for parameterized operators. Date values use YYYY-MM-DD format; DATERANGE uses two dates.
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {
   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "DATE",   "values": ["2018-12-28"]}]             }
      }
   }
}
```

STEP: 15 — Default value example: FROM (OData V4)
DESCRIPTION: FROM operator default value (YYYY-MM-DD).
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {
   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "FROM",   "values": ["2018-11-28"]}]

         }
      }
   }
}
```

STEP: 16 — Default value example: TO (OData V4)
DESCRIPTION: TO operator default value (YYYY-MM-DD).
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {
   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "TO",   "values": ["2019-11-02"]}]

         }
      }
   }
}
```

STEP: 17 — Default value example: DATERANGE (OData V4)
DESCRIPTION: DATERANGE requires two YYYY-MM-DD values: [from, to].
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {

   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "DATERANGE",   "values": ["2019-11-02","2022-01-01"]}]

         }
      }
   }
}
```

STEP: 18 — Default value example: TODAYFROMTO (OData V4)
DESCRIPTION: TODAYFROMTO takes two numeric parameters: days before TODAY and days after TODAY.
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {

   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "TODAYFROMTO", "values":[5,6]}]

         }
      }
   }
}
```

STEP: 19 — Default value example: LASTDAYS / NEXTDAYS / SpecificMonth (OData V4)
DESCRIPTION: Use numeric parameters for Last/Next X operators; SpecificMonth expects zero-based month number (January = 0).
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {

   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "LASTDAYS", "values":[6]}]
         }

      }
   }
}
```

STEP: 20 — Default value example: NEXTDAYS
DESCRIPTION: NEXTDAYS sample manifest defaultValues.
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {

   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "NEXTDAYS", "values":[6]}]
         }
      }
   }

}
```

STEP: 21 — Default value example: SPECIFICMONTH (OData V4)
DESCRIPTION: SPECIFICMONTH uses zero-based months; example sets January (0 or 1 depending on doc — sample shows 1 as example).
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {
   "filterFields": {
      "SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "SPECIFICMONTH", "values":[1]}]
         }
      }
   }

}
```

STEP: 22 — Semantic filter fields from navigation entity set (OData V4)
DESCRIPTION: When the filter field comes from a navigation entity set, reference it as "<navigationProperty>::<filterField>" in SelectionFields.filterFields.
LANGUAGE: JSON
CODE:
```json
"@com.sap.vocabularies.UI.v1.SelectionFields": {

   "filterFields": {
      "_Item::SalesOrderDate": {
         "settings": {
            "defaultValues" : [ {"operator": "SPECIFICMONTH", "values":[1]}]
         }
      }
   }

}
```

STEP: 23 — Exclude specific operators using operatorConfiguration (OData V4) — remove TODAY
DESCRIPTION: Use operatorConfiguration.path = "key" and equals/exclude to remove individual operators (allowed only for SingleRange-based Date fields).
LANGUAGE: JSON
CODE:
```json
"filterFields": {
    "SalesOrderDate": {
       "settings": {
           "operatorConfiguration": [
                 {
                     "path": "key",
                      "equals": "TODAY",
                      "exclude": true
                  } // TODAY filter will be removed
            ]
       }
    }
 }
```

STEP: 24 — Exclude/include multiple operators using operatorConfiguration (OData V4)
DESCRIPTION: Example to include "TODAY" and exclude "TODAYXYDAYS" via operatorConfiguration entries.
LANGUAGE: JSON
CODE:
```json
"filterFields": {
    "SalesOrderDate": {
       "settings": {
           "operatorConfiguration": [
                 {
                     "path": "key",
                      "equals": "TODAY",
                      "exclude": false
                  },
                  {
                    "path": "key",
                     "equals": "TODAYXYDAYS",
                     "exclude": true
                  }
            ]
       }
    }
 }
```

STEP: 25 — Supported operators for exclusion (OData V4)
DESCRIPTION: Use these operator keys with operatorConfiguration.exclude to hide/show specific operators for SingleRange Date fields.
LANGUAGE: JSON
CODE:
```json
[
 "DATE","FROM","TO","DATERANGE","TODAY","YESTERDAY","TOMORROW","TODAYFROMTO","LASTDAYS","NEXTDAYS","THISWEEK","LASTWEEK","LASTWEEKS","NEXTWEEK","NEXTWEEKS","SPECIFICMONTH","THISMONTH","LASTMONTH","LASTMONTHS","NEXTMONTH","NEXTMONTHS","THISQUARTER","LASTQUARTER","LASTQUARTERS","NEXTQUARTER","NEXTQUARTERS","QUARTER1","QUARTER2","QUARTER3","QUARTER4","THISYEAR","LASTYEAR","LASTYEARS","NEXTYEAR","NEXTYEARS","YEARTODATE","DATETOYEAR","Empty"
]
```

STEP: 26 — Additional combined FROM/TO operators (OData V4) — list
DESCRIPTION: New additional single-range operators that combine standard single-date operators with FROM or TO. These are not enabled by default and must be explicitly enabled in operatorConfiguration (exclude:false).
LANGUAGE: JSON
CODE:
```json
[
"FROMTODAY","FROMTOMORROW","FROMYESTERDAY","FROMFIRSTDAYWEEK","FROMLASTDAYWEEK","FROMFIRSTDAYMONTH","FROMLASTDAYMONTH","FROMFIRSTDAYQUARTER","FROMLASTDAYQUARTER","FROMFIRSTDAYYEAR","FROMLASTDAYYEAR",
"TOTODAY","TOTOMORROW","TOYESTERDAY","TOFIRSTDAYWEEK","TOLASTDAYWEEK","TOFIRSTDAYMONTH","TOLASTDAYMONTH","TOFIRSTDAYQUARTER","TOLASTDAYQUARTER","TOFIRSTDAYYEAR","TOLASTDAYYEAR"
]
```

STEP: 27 — Enable additional operators in manifest (OData V4)
DESCRIPTION: Example manifest snippet enabling additional FROM/TO operators by setting operatorConfiguration equals flags with exclude:false (they default to excluded).
LANGUAGE: JSON
CODE:
```json
"targets": {
   "SalesOrderManageList": {
      "options": {
         "settings": {
            "controlConfiguration": {
               "@com.sap.vocabularies.UI.v1.SelectionFields": {
                  "filterFields": {
                     "SalesOrderDate": {
                        "settings": {
                           "operatorConfiguration": [
                           {
                              "path": "key",
                              "equals": "FROMTODAY",
                              "exclude": false // By default, "exclude" is set to true for all these additional date range operators and have to be explicitly set to false in case the operator needs to be enabled
                           },
                          {
                             "path": "key",
                             "equals": "TOYESTERDAY",
                             "exclude": false
                          }]
                       }
                    },
                    …….
                    …….
                 }
```

STEP: 28 — Notes, precedence and constraints (Action items)
DESCRIPTION: Key action notes to apply while coding:
- customDateRangeImplementation takes precedence over filter and selectedValues.
- If custom fields or navigation fields are used, specify "<navigationProperty>::<propertyName>".
- Default manifest values are ignored if app state, navigation context, or URL provides a semantic date.
- Numeric defaultValue entries (e.g., FROM(val1)/TO(val2)) are not allowed; use operator-specific formats shown above.
- Excluding operators is allowed only for SingleRange-based Date fields; Edm.DateTime defaults mirror Edm.DateTimeOffset behavior for V4.
LANGUAGE: Text
CODE:
```text
- customDateRangeImplementation > filter > selectedValues precedence
- Use "<navigationProperty>::<propertyName>" for navigation-source filter fields
- Manifest defaults ignored if SelectionVariant or URL provides value
- Use operator-specific parameter formats; do not supply numeric FROM/TO ranges incorrectly
- Exclusion applies only to SingleRange date fields
```

fiori-elements-framework filter-bar semantic-dates manifest.json OData-V2 OData-V4 CDS XML JSON


**TITLE**: Enabling Simple Header Facets

**INTRODUCTION**: Enable the simple header facet to display additional content in the Object Page header for SAP Fiori elements (OData V2). This requires adding the simpleHeaderFacets flag in the app manifest (manifest.json) under the Object Page component settings.

**TAGS**: fiori-elements-framework, OData V2, manifest.json, object-page, simpleHeaderFacets, header-facet

**STEP**: 1 — Confirm applicability

**DESCRIPTION**: This feature applies only to SAP Fiori elements for OData V2. Verify your app uses OData V2 before enabling the flag.

**LANGUAGE**: Plain text

**CODE**:
```text
Note: This topic is only applicable to SAP Fiori elements for OData V2.
```

**STEP**: 2 — Add the simpleHeaderFacets flag in manifest.json

**DESCRIPTION**: Edit your app's manifest.json. Within the "sap.ui.generic.app" → pages array find the ObjectPage component settings and add "simpleHeaderFacets": true. The flag must be added in the Object Page component's "settings" object. File path: manifest.json (root of your UI5 application).

Preserve the structure and placement as shown in the example below.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.ui.generic.app": {
        "_version": "1.2.0",

        "pages": [{
                "entitySet": "STTA_C_MP_Product",
                "component": {
                        "name": "sap.suite.ui.generic.template.ListReport",
                        "list": true,
                        "settings": {
                                "gridTable": false,
                                "multiSelect": true,
                                "smartVariantManagement": true
                        }
                },
                "pages": [{
                        "entitySet": "STTA_C_MP_Product",
                        "component": {
                                "name": "sap.suite.ui.generic.template.ObjectPage",
                                "settings": {
                                        "showRelatedApps": true,
                                        "gridTable": false,
                                        "editableHeaderContent": true,
                                        "simpleHeaderFacets":true, // This Enables Simple Header Facet on the Object Page
                                }
                        },
                        "pages": [{
                                "navigationProperty": "to_ProductText",
                                "entitySet": "STTA_C_MP_ProductText",
                                "component": {
                                        "name": "sap.suite.ui.generic.template.ObjectPage"
                                }
                        }]
                }]
        }]
},
```

**STEP**: 3 — Understand limitations and supported content

**DESCRIPTION**: The simple header facet supports placing additional header content but does NOT support complex data points created via DataFieldForAnnotation (for example: ratings, progress indicators, charts). Only simple header facets should be used for additional header content.

**LANGUAGE**: Plain text

**CODE**:
```text
Note: The simple header facet does not support the use of complex data points and DataFieldForAnnotation, such as ratings, progress indicators, or charts.
```

Enabling Simple Header Facets

fiori-elements-framework
OData V2
manifest.json
object-page
simpleHeaderFacets
header-facet


**TITLE**: Enabling Standard List Items and Object List Items (Fiori elements, OData V2)

**INTRODUCTION**: Configure UI.LineItem annotations and manifest.json settings to render StandardList and ObjectList items in Fiori elements (OData V2). Includes required annotation XML samples, manifest.json snippets, and mapping of annotation elements to UI positions and behavior (importance, data points, criticality, image URL).

**TAGS**: fiori-elements-framework, OData V2, UI.LineItem, DataField, DataFieldForAnnotation, DataPoint, manifest.json, StandardList, ObjectList, UI.Criticality

STEP: 1 — General rules and prerequisites

DESCRIPTION: Apply these rules before adding annotations. This topic is applicable only to SAP Fiori elements for OData V2. Use the guidelines below when authoring UI.LineItem, DataField, DataFieldForAnnotation, and DataPoint annotations. Ensure internal navigation extension (onListNavigationExtension) is enabled for internal navigation if required.

- UI.LineItem is the default annotation term used to render a list item similar to a table. UI.LineItem must contain only UI.DataField and UI.DataFieldForAnnotation elements. Other DataFieldAbstract types are not supported.
- UI.DataFieldForAnnotation with a DataPoint target is used for fields displayed on the right side of the list item. If no DataPoint exists for those positions, UI.DataField is used.
- Fields are sorted by their UI.Importance (High, Medium, Low). If a DataPoint exists, it will be used regardless of the DataField importance. Default importance = Medium when UI.Importance is not defined.
- Standard and Object list items support UI.Criticality so data points can drive semantic coloring.
- onListNavigationExtension is enabled for internal navigation. See Example: Enable Internal Navigation to Different Detail Page (example-enable-internal-navigation-to-different-detail-page-75002b3.md).

LANGUAGE: text

CODE:
```text
- Applicable only to SAP Fiori elements for OData V2.
- UI.LineItem must contain only UI.DataField and UI.DataFieldForAnnotation.
- Use UI.DataFieldForAnnotation (Target = @UI.DataPoint#<Qualifier>) to show right-side fields (data points).
- If no DataPoint exists for a right-side slot, a UI.DataField is used instead.
- Default importance = UI.ImportanceType/Medium when not specified.
- UI.Criticality supported on data points for semantic coloring.
- Enable onListNavigationExtension for internal navigation (see referenced example).
```

STEP: 2 — Standard List Item: Add UI.LineItem annotation (annotation XML)

DESCRIPTION: Add the UI.LineItem annotation with DataField and DataFieldForAnnotation entries. Add a UI.DataPoint qualifier (Price) used by DataFieldForAnnotation. Place these annotations in your service annotations file (for example annotations.xml) or OData annotation provider used by the app.

LANGUAGE: XML

CODE:
```xml
<Annotation Term="UI.LineItem">
	<Collection>
		<Record Type="UI.DataField">
			<PropertyValue Property="Value" Path="ProductForEdit" />
			<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
		</Record>
		<Record Type="UI.DataField">
			<PropertyValue Property="Value" Path="ProductCategory" />
			<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/Medium" />
		</Record>
		<Record Type="UI.DataField">
			<PropertyValue Property="Value" Path="ProductPictureURL" />
		</Record>
		<Record Type="UI.DataFieldForAnnotation">
			<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Price" />
		</Record>
	</Collection>
</Annotation>

<Annotation Term="UI.DataPoint" Qualifier="Price">
	<Record>
		<PropertyValue Property="Value" Path="Price" />
		<PropertyValue Property="Criticality" Path="PriceCriticality" />
	</Record>
</Annotation>
```

STEP: 3 — Standard List Item: Update manifest.json to use StandardList

DESCRIPTION: Update the app manifest.json to configure the List Report page to use a StandardList table type and optional settings like isWorklist and smartVariantManagement. Place this under the "pages" section for the corresponding ListReport page id.

LANGUAGE: JSON

CODE:
```json
"pages": {
	"ListReport|STTA_C_MP_Product": {
		"entitySet": "STTA_C_MP_Product",
		"component": {
			"settings": {
				"isWorklist": true,
				"tableSettings": {
					type: "StandardList"
				},
				"smartVariantManagement": false
			}
		}
	}
}
```

STEP: 4 — Standard List Item: Mapping of UI.LineItem entries to UI roles

DESCRIPTION: Follow these mappings when ordering DataField and DataPoint entries under UI.LineItem. DataPoints occupy right-side UI locations and can override DataField placement. If DataPoint is missing for a right-side slot, the next DataField is used.

LANGUAGE: text

CODE:
```text
Standard List Item Property -> Entity Annotation -> Location on List Item UI -> Additional comments

title
- First data field of UI.LineItem
- Top left

description
- Second data field of UI.LineItem
- Bottom left

info
- First data point
- Top right
- If no data point exists, the next data field is used (third data field).

infoState
- First data point or criticality, or first data point or CriticalityCalculation
- Color
- If no data point exists, default state = None.

icon
- First data field marked with UI.IsImageURL annotation
- (Location not order-sensitive)
- This data field can be placed anywhere under UI.LineItem; order is not important.
```

STEP: 5 — Object List Item: Add UI.LineItem annotation (annotation XML)

DESCRIPTION: Add UI.LineItem annotation tailored for ObjectList layout. Include DataField entries for attributes and DataFieldForAnnotation entries that reference DataPoints with qualifiers (NetAmount, GrossAmount, TaxAmount). Add DataPoint annotations with Criticality values. Place these in your service annotations file (annotations.xml) or OData annotation provider.

LANGUAGE: XML

CODE:
```xml
<Annotation Term="UI.LineItem">
	<Collection>
		<Record Type="UI.DataField">
			<PropertyValue Property="Label" String="Sales Order ID" />
			<PropertyValue Property="Value" Path="SalesOrderID"/>
			<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
		</Record>
		<Record Type="UI.DataField">
			<PropertyValue Property="Value" Path="BusinessPartnerID"/>
			<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/Medium"/>
		</Record>
		<Record Type="UI.DataField">
			<PropertyValue Property="Value" Path="CurrencyCode"/>
			<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/Low"/>
		</Record>
		<Record Type="UI.DataFieldForAnnotation">
			<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
			<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#NetAmount" />
		</Record>
		<Record Type="UI.DataFieldForAnnotation">
			<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#GrossAmount" />
		</Record>
		<Record Type="UI.DataFieldForAnnotation">
		<Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/Low"/>
			<PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#TaxAmount" />
		</Record>
    </Collection>
</Annotation>

<Annotation Term="UI.DataPoint" Qualifier="NetAmount">
	<Record>
		<PropertyValue Property="Value" Path="NetAmount" />
		<PropertyValue Property="Criticality" EnumMember="com.sap.vocabularies.UI.v1.CriticalityType/Positive" />
	</Record>
</Annotation>
<Annotation Term="UI.DataPoint" Qualifier="GrossAmount">
	<Record>
		<PropertyValue Property="Value" Path="GrossAmount" />
		<PropertyValue Property="Criticality" EnumMember="com.sap.vocabularies.UI.v1.CriticalityType/Negative" />
	</Record>
</Annotation>
<Annotation Term="UI.DataPoint" Qualifier="TaxAmount">
	<Record>
		<PropertyValue Property="Value" Path="TaxAmount" />
		<PropertyValue Property="Criticality" EnumMember="com.sap.vocabularies.UI.v1.CriticalityType/Critical" />
	</Record>
</Annotation>
```

STEP: 6 — Object List Item: Update manifest.json to use ObjectList

DESCRIPTION: Update manifest.json "pages" section for the ListReport page to set tableSettings.type to "ObjectList". Place this snippet under the app's manifest pages configuration.

LANGUAGE: JSON

CODE:
```json
"pages": {
	"ListReport|STTA_C_MP_Product": {
		"entitySet": "STTA_C_MP_Product",
		"component": {
			"settings": {
				"isWorklist": true,
				"tableSettings": {
					type: "ObjectList"
  				},
				"smartVariantManagement": false
			}
		}
	}
}
```

STEP: 7 — Object List Item: Mapping of UI.LineItem entries to UI roles

DESCRIPTION: Use this mapping when creating ObjectList annotations. DataPoints and DataFields map to title, attributes, number, statuses, and their visual positions. If DataPoints are missing for a slot, subsequent DataFields are used according to the fallback rules described.

LANGUAGE: text

CODE:
```text
Object List Item Property -> Entity Annotation -> Location on List Item UI -> Additional comments

title
- First data field of UI.LineItem
- Top left

First ObjectAttribute (under attributes aggregation)
- Second data field of UI.LineItem
- Middle left

number
- First data point
- Top right
- If no data point exists, the next data field (third data field) is used.

numberState
- First data point or criticality, or first data point or CriticalityCalculation
- Color
- If no data point exists, default state = None.

firstStatus
- Second data point
- Middle right
- If no data point exists, the next data field is used (third data field if one data point provided, fourth if none provided).

Second ObjectAttribute (under attributes aggregation)
- Third data field
- Bottom left
- If third data field is already used, the next available data field is used (e.g., fifth if no data points, or fourth if one data point provided).

secondStatus
- Third data point
- Bottom right
- If no data points exist, the next data field is used (fourth data field if two data points provided, fifth if one provided, sixth if none provided).
```

fiori-elements-framework
OData V2
UI.LineItem
DataField
DataFieldForAnnotation
DataPoint
manifest.json
StandardList
ObjectList
UI.Criticality


**TITLE**: Enabling Stream Support (OData V2 & V4) for SAP Fiori Elements

**INTRODUCTION**: Practical, code-focused reference showing required entity properties and annotations to enable file upload/download/delete (stream support) in SAP Fiori elements apps for OData V2 and V4. Includes security prerequisites, V2 and V4 annotation examples, UI field mapping, UI rendering rules, and file upload as action parameter (XML, ABAP CDS, CAP CDS examples). Use these snippets directly in your service/annotation files.

**TAGS**: fiori-elements, odata-v2, odata-v4, streams, file-upload, annotations, CAP, CDS, ABAP, XML, MediaType, ContentDisposition

STEP: Security prerequisites

DESCRIPTION: Mandatory security checks and back-end measures to implement before enabling stream support. Ensure virus scanning, size limits, MIME-type restrictions, and file validation. Define acceptable media types via annotation. See security configuration doc for details.

LANGUAGE: text

CODE:
```text
Security checklist (implement in back end & metadata):

- Add Core.AcceptableMediaTypes annotation on the entity/property to whitelist upload MIME types.
- Ensure back-end service framework performs virus scanning and enforces maximum file size and MIME-type restrictions.
- Implement file validation and data sanitization in the back end.
- Reference: security-configuration-ba0484b.md
```

STEP: Prerequisite for OData V2 (entity must be stream enabled)

DESCRIPTION: OData V2 requires an EntityType with HasStream="true" to support media streams. Add key properties and other fields as needed.

LANGUAGE: XML

CODE:
```xml
<EntityType Name="MyStreamType" m:HasStream="true" sap:label="Stream Test" sap:content-version="1">
  <Key>
    <PropertyRef Name="Streamuuid" />
    <PropertyRef Name="IsActiveEntity" />
  </Key>
  <Property Name="Edit_ac" Type="Edm.Boolean" sap:label="Dyn. Action Control" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
</EntityType>
```

STEP: Enable stream field on Object Page (OData V2)

DESCRIPTION: Annotate a UI.FieldGroup or UI.Identification with a UI.DataField where Value path is the reserved $value to enable stream UI (uploader/link/thumbnail). Also annotate entity-level MediaType, optionally UI.IsImage, and ContentDisposition Filename path. Restrict upload MIME types using Core.AcceptableMediaTypes. Notes on behavior: draft apps require editable UI for upload/delete; non-draft support is in display mode. Only one file per record; uploading a second file replaces the existing one.

LANGUAGE: XML

CODE:
```xml
<!-- Use $value in a UI.DataField to bind the stream -->
<Record Type="UI.DataField">
    <PropertyValue Property="Value" Path="$value"/>
</Record>

<!-- Entity-level: specify MediaType property used for the stream -->
<Annotation Term="Org.OData.Core.V1.MediaType" Path="ThisMimeType"></Annotation>

<!-- Optional: render stream as image thumbnails -->
<Annotation Term="UI.IsImage"/>

<!-- ContentDisposition: specify file name property (if missing, UI shows "Open File") -->
<Annotation Term="SAP__core.ContentDisposition">
    <Record>
        <PropertyValue Property="Filename" Path="ThisFileName" />
    </Record>
</Annotation>

<!-- Restrict accepted media types for upload -->
<Annotation Term="Core.AcceptableMediaTypes">
    <Collection>
        <String>text/plain</String>
    </Collection>
</Annotation>
```

STEP: OData V4 — Step 1: Add Edm.Stream property and related properties

DESCRIPTION: Define Edm.Stream property, a property holding media type, optional MaxLength for file size, and acceptable media types annotations. Annotate the stream property with Core.MediaType pointing to the media-type property. Mark media-type property with Core.IsMediaType.

LANGUAGE: XML

CODE:
```xml
<EntityType Name="MainEntities">
    ...
    <Property Name="myStreamProperty" Type="Edm.Stream" />
    <Property Name="myStreamPropertyType" Type="Edm.String" />
    <Property Name="myRestrictedStreamProperty" Type="Edm.Stream" MaxLength="100000"/>
    ...
</EntityType>
<Annotations Target="sap.fe.stream.StreamsService.MainEntities/myStreamProperty">
    <Annotation Term="Core.MediaType" Path="myStreamPropertyType" />
</Annotations>
<Annotations Target="sap.fe.stream.StreamsService.MainEntities/myStreamPropertyType">
    <Annotation Term="Core.IsMediaType" Bool="true" />
</Annotations>
<Annotations Target="sap.fe.stream.StreamsService.MainEntities/myRestrictedStreamProperty">
    <Annotation Term="Core.MediaType" String="text/plain"/>
    <Annotation Term="Core.AcceptableMediaTypes">
        <Collection>
            <String>text/plain</String>
        </Collection>
    </Annotation>
</Annotations>
```

STEP: OData V4 — Step 2: Add UI DataField for stream property

DESCRIPTION: Add a UI.FieldGroup (qualifier optional) and include a UI.DataField referencing the Edm.Stream property via Value Path. This will render the uploader / link / preview in forms.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="sap.fe.stream.StreamsService.MainEntities">
    <Annotation Term="UI.FieldGroup" Qualifier="streams">
        <Record Type="UI.FieldGroupType">
            <PropertyValue Property="Label" String="Streams" />
            <PropertyValue Property="Data">
                <Collection>
                    <Record Type="UI.DataField">
                        <PropertyValue Property="Label" String="Stream" />
                        <PropertyValue Property="Value" Path="myStreamProperty" />
                    </Record>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

STEP: UI representation rules (OData V4)

DESCRIPTION: Implementation rules for how Fiori Elements renders streams:
- Document icon is derived from odata.mediaContentType mapping; fallback to generic icon.
- Link text uses Core.ContentDisposition/Filename if present and non-empty; otherwise "Open File".
- If odata.mediaContentType is null => stream is empty => empty indicator shown.
- Avatar rendered when UI.IsImage is set or Core.MediaType starts with "image/".
- Use MaxLength to restrict file size (bytes). Use Core.AcceptableMediaTypes to restrict MIME types.

LANGUAGE: XML

CODE:
```xml
<!-- Example: dynamic media type with filename -->
<Annotations Target="sap.fe.streams.StreamsService.MainEntities/streamWithFilename_content">
     <Annotation Term="Core.MediaType" Path="streamWithFilename_type"/>
          <Annotation Term="Core.ContentDisposition">
               <Record Type="Core.ContentDispositionType">
                    <PropertyValue Property="Filename" Path="streamWithFilename_name"/>
               </Record>
          </Annotation>
     <Annotation Term="Common.Label" String="Stream, dynamic media type, with name"/>
</Annotations>
```

STEP: UI mapping example (CAP CDS snippet for stream + filename + media type)

DESCRIPTION: CAP CDS example that shows how to annotate stream, media type, and filename in CDS. Use @Core.MediaType to point to MediaType property and @Core.ContentDisposition.Filename to point to filename property.

LANGUAGE: CDS

CODE:
```cddl
@title : 'Stream with file name'
@Core.MediaType : streamWithFilename_type
@Core.ContentDisposition.Filename : streamWithFilename_name
                                    streamWithFilename_content : Stream;
                                    streamWithFilename_type : MediaType;
                                    streamWithFilename_name : StreamName;
```

STEP: File upload as Action Parameter — XML Annotation

DESCRIPTION: Define an Action that takes a ComplexType parameter containing an Edm.Stream, MIME type, and FileName. Annotate the ComplexType stream property with Core.ContentDisposition.Filename, Core.MediaType, Core.AcceptableMediaTypes, and mark MIME property with Core.IsMediaType. Use MaxLength on stream property to restrict file size.

LANGUAGE: XML

CODE:
```xml
<Action Name="ActionParameterTypeName" IsBound="true">
  <Parameter Name="_it" Type="service.namespace.EntityTypeName" Nullable="false"/>
  <Parameter Name="_StreamProperties" Type="service.namespace.FileStreamTypeName" Nullable="false"/>
</Action>

<ComplexType Name="FileStreamTypeName">
  <Property Name="StreamProperty" Type="Edm.Stream" Nullable="false" MaxLength="128" />
  <Property Name="MimeType" Type="Edm.String" Nullable="false" />
  <Property Name="FileName" Type="Edm.String" Nullable="false" />
</ComplexType>

<Annotations Target="service.namespace.FileStreamTypeName/StreamProperty">
  <Annotation Term="Common.Label" String="Label for File Upload" />
  <Annotation Term="Core.ContentDisposition">
    <Record>
      <PropertyValue Property="Filename" Path="FileName" />
    </Record>
  </Annotation>
  <Annotation Term="Core.MediaType" Path="MimeType" />
  <Annotation Term="Core.AcceptableMediaTypes">
    <Collection>
      <String>image/png</String>
    </Collection>
  </Annotation>
</Annotations>
<Annotations Target="service.namespace.FileStreamTypeName/MimeType">
  <Annotation Term="Core.IsMediaType" />
</Annotations>
```

STEP: File upload as Action Parameter — ABAP CDS example

DESCRIPTION: ABAP CDS pattern for defining a file-stream complex type and an action parameter referencing it. Use Semantics annotations to link stream, mimetype, and filename.

LANGUAGE: ABAP CDS

CODE:
```abap
// ==== FILE_STREAM_TYPE_NAME ==== //

// == CDS View for FILE_STREAM_TYPE_NAME
define root abstract entity FILE_STREAM_TYPE_NAME
{
  @Semantics.largeObject.mimeType: 'mimetype'
  @Semantics.largeObject.fileName: 'filename'
  @Semantics.largeObject.contentDispositionPreference: #INLINE
  streamproperty : abap.rawstring(0);

  @UI.hidden: true
  mimetype : abap.char(128);

  @UI.hidden: true
  filename : abap.char(128);
}

// == Behavior Definitions for FILE_STREAM_TYPE_NAME
abstract;
strict;
with hierarchy;
define behavior for FILE_STREAM_TYPE_NAME {}

// ==== ACTION_PARAMETER_TYPE_NAME ==== //

// == CDS View for ACTION_PARAMETER_TYPE_NAME
define root abstract entity ACTION_PARAMETER_TYPE_NAME
{
  _StreamProperties : association [1] to FILE_STREAM_TYPE_NAME on 1 = 1;
}

// == Behavior Definitions for ACTION_PARAMETER_TYPE_NAME
abstract;
strict;
with hierarchy;
define behavior for ACTION_PARAMETER_TYPE_NAME
{
  association _StreamProperties with hierarchy;
}
```

STEP: File upload as Action Parameter — CAP CDS example

DESCRIPTION: CAP CDS action and complex type definition showing LargeBinary usage and annotations for media type and filename.

LANGUAGE: CDS

CODE:
```cddl
action ActionParameterTypeName(
  _StreamProperties : service.namespace.FileStreamTypeName not null
) returns EntityTypeName;

type FileStreamTypeName {
  StreamProperty       : LargeBinary @Core.MediaType: MimeType @Core.ContentDisposition.Filename: FileName;
  MimeType             : String @Core.IsMediaType;
  FileName             : String;
};
```

fiori-elements odata-v2 odata-v4 streams file-upload annotations CAP CDS ABAP XML MediaType ContentDisposition


**TITLE**: Enabling Sub-object Creation Through Dialog on a Non-draft Object Page (OData V2)

**INTRODUCTION**: Enable creation of related (sub-)objects with up to 8 data fields via a dialog on an Object Page in non-draft SAP Fiori elements (OData V2). This document shows the manifest settings to add, constraints to follow, and how to override dialog title and success toast i18n keys.

**TAGS**: fiori-elements-framework, OData V2, manifest, object-page, create-dialog, non-draft, i18n, related-entity

**STEP**: 1 - Add createWithParameterDialog fields mapping (template)
**DESCRIPTION**: In the manifest, add the createWithParameterDialog property and map fields to their respective entity properties. Use this template to declare the fields that appear in the create dialog. Keep placeholders for actual field names and paths.
**LANGUAGE**: JSON
**CODE**:
```json
"createWithParameterDialog" : {
       "fields" : {
         "<fieldname1>" : {"path":"<fieldname1>"},
         "<fieldname2>" : {"path":"<fieldname2>"}
        }
```

**STEP**: 2 - Example: Add createWithParameterDialog to a section's tableSettings in pages
**DESCRIPTION**: Example manifest fragment showing how to enable the create dialog for a related entityset inside an Object Page section. Copy this structure under your pages[] -> component.settings.sections -> <sectionKey> to enable the dialog for the related table. Replace entitySet, navigationProperty and field names with your actual values.
**LANGUAGE**: JSON
**CODE**:
```json
"pages": [
           {
             "entitySet": "STTA_C_SO_SalesOrder_ND",
              "component": {
                  "name": "sap.suite.ui.generic.template.ObjectPage",
                  "settings": {
                    "showRelatedApps": true,
                     "gridTable": false,
                      "sections": {
                         "to_Item::com.sap.vocabularies.UI.v1.LineItem": {
                         "navigationProperty": "to_Item",
                          "entitySet": "STTA_C_SO_SalesOrderItem_ND",
                           "tableSettings": {
                             "createWithParameterDialog" : {
                               "fields" : {
                                 "SalesOrderItemID":{"path": "SalesOrderItemID"},
                                  "ProductID" : {"path":"ProductID"},
                                  "Quantity" : {"path":"Quantity"}
                                 }
                               }
                            }
                          }
                       }
                    }
                  },
```

**STEP**: 3 - Constraints and validation checklist
**DESCRIPTION**: Apply these rules when enabling createWithParameterDialog.
**LANGUAGE**: Plaintext
**CODE**:
```
- Applicable only for SAP Fiori elements with OData V2.
- Use only on non-draft applications (do not enable for draft-enabled apps).
- The create dialog supports a maximum of 8 data fields.
- Ensure each listed property is part of the related entity (correct entity path).
- Include all mandatory fields of the target entity in the create dialog fields mapping.
- Validate navigationProperty and entitySet names are correct for the section.
```

**STEP**: 4 - Customize dialog title and success toast via i18n
**DESCRIPTION**: Override the default dialog title and success toast by setting i18n keys CREATE_DIALOG_TITLE and ITEM_CREATED in your i18n properties file. Add or modify these keys in your i18n file to change the dialog title and success message.
**LANGUAGE**: properties
**CODE**:
```
CREATE_DIALOG_TITLE=New Item
ITEM_CREATED=Item Created
```

**STEP**: 5 - Implementation notes and recommended actions
**DESCRIPTION**: Practical actions to implement and test the feature.
**LANGUAGE**: Plaintext
**CODE**:
```
- Add createWithParameterDialog under the specific section.tableSettings where related items are shown.
- Replace placeholder field names and entitySet/navigationProperty with actual application values.
- Update i18n keys to localized texts if needed.
- Deploy and test on a non-draft app, create a related item via the Object Page and verify:
  - Dialog appears with the mapped fields (<= 8 fields).
  - Mandatory fields are present and validated.
  - On success, the customized ITEM_CREATED toast appears (if overridden).
```

fiori-elements-framework
OData V2
manifest
object-page
create-dialog
non-draft
i18n
related-entity


**TITLE**: Enabling Table Personalization in SAP Fiori Elements (OData V2 & V4)

**INTRODUCTION**: Quick reference for enabling and configuring table personalization (columns, sorting, filtering, grouping) in SAP Fiori Elements apps. Includes actionable manifest.json settings and annotation examples (XML, ABAP CDS, CAP CDS) to control filter/sort availability and restrictions for OData V2 and OData V4.

**TAGS**: fiori-elements, table-personalization, manifest.json, annotations, SortRestrictions, personalization, ODataV2, ODataV4

**STEP**: 1 — Defaults and variant-management behavior

**DESCRIPTION**: Understand default filter behavior and the impact of variant management levels.
- Default filtering behavior for list report page tables:
  - Disabled in page-level variant management (harmonized variant management).
  - Enabled in control-level variant management.
- In harmonized (page-level) variant management, end users cannot set table filters unless explicitly enabled.
- If smartVariantManagement = false, table filters are enabled by default.

**LANGUAGE**: text

**CODE**:
```text
Defaults:
- Page-level variant: table filtering disabled.
- Control-level (control) variant: table filtering enabled.
- smartVariantManagement: false => table filter enabled by default.
```

**STEP**: 2 — Enable table filters for OData V2 (manifest.json)

**DESCRIPTION**: To allow end users to set filters in table personalization when using harmonized variant management, set enableTableFilterInPageVariant to true in the manifest. Place this setting in the page component settings for the ListReport.

**LANGUAGE**: JSON

**CODE**:
```json
manifest.json

"sap.ui.generic.app": {
    "_version": "1.3.0",
        "settings": {
        "forceGlobalRefresh": true
        },
        "pages": {
            "ListReport|STTA_C_MP_Product": {
                "entitySet": "STTA_C_MP_Product",
                "component": {
                    "name": "sap.suite.ui.generic.template.ListReport",
                    "list": true,
                    "settings": {
                        "smartVariantManagement": true,
                        "enableTableFilterInPageVariant": true
                    }
                },
```

**STEP**: 3 — Table personalization defaults and control in OData V4 (overview)

**DESCRIPTION**: For OData V4, table personalization is enabled by default (add/remove columns, filter, sort, group). Use annotations to exclude properties from filtering/sorting or to restrict navigation properties. Key considerations:
- Use @com.sap.vocabularies.UI.v1.HiddenFilter to exclude columns from being filterable.
- Filtering of navigation properties is available only for properties used in the LineItem.
- In list reports with page-level variant management, enable filtering by setting "filter": true in a personalization object in the manifest (see Step 4).
- Use OData Capabilities annotations (SortRestrictions, NavigationRestrictions) to restrict sorting.
- Caution: sorting on navigation properties can cause issues in CAP Node.js with SQLite.

**LANGUAGE**: text

**CODE**:
```text
OData V4 table personalization:
- Default: personalization enabled (columns, filter, sort, group).
- Use @UI.HiddenFilter to exclude filterable columns.
- Filtering nav properties: only if used in LineItem.
- Use NavigationRestrictions and SortRestrictions to control sorting.
- Note: Sorting on currency/unit fields sorts currency/unit first, then amount.
- Caution: CAP NodeJS + SQLite may have issues when sorting on navigation properties.
```

**STEP**: 4 — Restrict sorting using NavigationRestrictions / SortRestrictions (XML annotation)

**DESCRIPTION**: Example XML annotation to restrict sorting on navigation properties and specific nested properties. Use in service metadata annotations for OData V4.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="Capabilities.NavigationRestrictions">
    <Record Type="Capabilities.NavigationRestrictionsType">
        <PropertyValue Property="RestrictedProperties">
            <Collection>
                <Record Type="Capabilities.NavigationPropertyRestriction">
                    <PropertyValue Property="NavigationProperty" NavigationPropertyPath="_OverallSDProcessStatus"/>
                    <PropertyValue Property="SortRestrictions">
                        <Record Type="Capabilities.SortRestrictionsType">
                            <PropertyValue Property="NonSortableProperties">
                                <Collection>
                                    <PropertyPath>_OverallSDProcessStatus/OverallSDProcessStatus_Text</PropertyPath>
                                </Collection>
                            </PropertyValue>
                        </Record>
                    </PropertyValue>
                </Record>
                <Record Type="Capabilities.NavigationPropertyRestriction">
                    <PropertyValue Property="NavigationProperty" NavigationPropertyPath="_SalesOrderType"/>
                    <PropertyValue Property="SortRestrictions">
                        <Record Type="Capabilities.SortRestrictionsType">
                            <PropertyValue Property="NonSortableProperties">
                                <PropertyValue Property="Sortable" Bool="false"/>
                            </PropertyValue>
                        </Record>
                    </PropertyValue>
                </Record>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

**STEP**: 5 — Restrict sorting using ABAP CDS

**DESCRIPTION**: Example ABAP CDS annotation to disable sorting on an entity or property.

**LANGUAGE**: ABAP

**CODE**:
```abap
@ObjectModel.sort.enabled: false
```

**STEP**: 6 — Restrict sorting using CAP CDS (Node.js / CAP model)

**DESCRIPTION**: CAP CDS-style definition showing NavigationRestrictions with SortRestrictions for navigation properties. Use in CAP model definitions or manifest-adjacent configuration depending on project.

**LANGUAGE**: CDS

**CODE**:
```cds
NavigationRestrictions : {
    RestrictedProperties : [
        {
            NavigationProperty: _OverallSDProcessStatus,
            SortRestrictions: {NonSortableProperties: [_OverallSDProcessStatus.OverallSDProcessStatus_Text]}
        },
        {
            NavigationProperty: _SalesOrderType,
            SortRestrictions: {Sortable: false}
        }
    ]
}
```

**STEP**: 7 — Configure personalization in manifest.json (choose which features are available)

**DESCRIPTION**: Use the "personalization" setting under the component options (LineItem tableSettings) to enable/disable column, sort, filter, and group behavior. Values:
- true: all personalization options enabled (default).
- false: all disabled.
- object: define properties (column, sort, filter, group). Omit = treated as false for safety across releases.

Place this configuration under the component options for the ListReport or relevant page component.

**LANGUAGE**: JSON

**CODE**:
```json
manifest.json

"BusinessPartnersList": {
    "type": "Component",
    "id": "BusinessPartnersList",
    "name": "sap.fe.templates.ListReport",
    "options": {
        "settings": {
            "contextPath": "/BusinessPartners",
            "variantManagement": "Control",
            "controlConfiguration": {
                "@com.sap.vocabularies.UI.v1.LineItem": {
                    "tableSettings": {
                        "type": "AnalyticalTable",
                        "personalization": {
                            "column" : true,
   	                        "sort" : false,
   	                        "filter" : true,
                	        "group": true
  	                    }
                    }
                }
            }
        }
    }
},
```

**STEP**: 8 — Rules for personalization with TextArrangement

**DESCRIPTION**: Apply these rules when properties use TextArrangement:
- Sorting and grouping are available for visible items:
  - For TextFirst: both property and text can be sorted/grouped.
  - For TextOnly: only the text is visible; sorting/grouping available for text. Filtering applies to the property itself (not text) unless the text property has no filter restriction.
- When TextOnly text is annotated UI.Hidden = true, that Hidden annotation is ignored for sorting/grouping; text can still be sorted/grouped.
- If a presentationVariant sets sortOrder on a TextOnly property, sorting applies to the property (not the text). Sort indicator won't show in the visible column header (property not visible).
- If the TextArrangement target is a navigation property, that target is not shown in the personalization Columns tab unless explicitly defined in LineItem or a custom column.

**LANGUAGE**: text

**CODE**:
```text
TextArrangement rules:
- TextFirst: property or text can be sorted/grouped.
- TextOnly: sorting/grouping only on text; filtering on property itself (text filter may be available if not restricted).
- UI.Hidden on text property is ignored for sort/group (text still available).
- PresentationVariant sortOrder on TextOnly property sorts the property; sort indicator hidden if property not visible.
- TextArrangement target that is a navigation property appears in Columns only if included in LineItem or a custom column.
```


**TITLE**: Enable and Configure Flexible Column Layout (FCL) in SAP Fiori Elements

**INTRODUCTION**: This guide shows how to enable and configure the Flexible Column Layout (FCL) for SAP Fiori Elements applications (OData V2 and V4). It includes actionable steps for enabling FCL with SAP Fiori Tools, required manifest.json changes (rootView, router config, routing targets), examples for 2- and 3-column scenarios, default layout overrides, personalization (column resize saving), and known restrictions.

**TAGS**: sap.fiori, fcl, flexible-column-layout, manifest.json, sap.fe, routing, sap.ui5, ODataV2, ODataV4, sap.f.routing.Router

**STEP**: 1 — Overview of FCL options and properties

**DESCRIPTION**: Use these manifest properties to control default behavior of the FCL. Set globally under "sap.ui.generic.app" (OData V2) or router config (OData V4). Values shown are the supported default layout types.

- defaultTwoColumnLayoutType: TwoColumnsBeginExpanded | TwoColumnsMidExpanded
- defaultThreeColumnLayoutType: ThreeColumnsMidExpanded | ThreeColumnsEndExpanded
- defaultLayoutType (per-page override): e.g., OneColumn, MidColumnFullScreen, etc.

End users can expand, collapse, and set full-screen on columns via UI buttons. Column resize state is persisted per application and device type (desktop/tablet/phone) in personalization settings.

**LANGUAGE**: none

**CODE**:
```text
Properties (examples):
- defaultTwoColumnLayoutType: TwoColumnsBeginExpanded | TwoColumnsMidExpanded
- defaultThreeColumnLayoutType: ThreeColumnsMidExpanded | ThreeColumnsEndExpanded
- defaultLayoutType (per page): OneColumn | MidColumnFullScreen | ...
```

**STEP**: 2 — Enable FCL using SAP Fiori Tools (Page Map)

**DESCRIPTION**: Use SAP Fiori Tools Page Map to enable and preview FCL quickly. Steps are action-oriented for UI tooling:

1. Open the Page Map (e.g., right-click project folder → Show Page Map).
2. In the Property Panel, toggle "Flexible Column Layout" on.
3. Choose the desired two- or three-column layout. Optionally customize layout keys in manifest.json.
4. Preview the application (Previewing an Application) to verify behavior.

Note: FCL is not available for the Overview Page floorplan. Analytical List Page supports only TwoColumnsBeginExpanded. FCL works in draft and non-draft apps.

**LANGUAGE**: none

**CODE**:
```text
No code required: use Page Map in SAP Fiori Tools → Property Panel → Flexible Column Layout → select layout → Preview
```

**STEP**: 3 — Enable FCL in manifest.json (OData V2)

**DESCRIPTION**: Add a flexibleColumnLayout entry under "sap.ui.generic.app" → "settings". This sample shows global defaults for two- and three-column types. Place in your manifest.json.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.ui.generic.app": {
        "_version": "1.1.0",
        "settings": {
            "flexibleColumnLayout": {
                "defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
                "defaultThreeColumnLayoutType": "ThreeColumnsEndExpanded"
            }
        },
        "pages": [...
```

**STEP**: 4 — Define per-page default layout (OData V2)

**DESCRIPTION**: Override global defaults per page using "defaultLayoutType" inside the page definition. Common use: set an object page to "OneColumn" so it moves to the first column on open, or "MidColumnFullScreen" to open full-screen. This is useful when pages in the same column require different initial layouts.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.ui.generic.app": {
    "settings": {
            "flexibleColumnLayout": {
                "defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
                "defaultThreeColumnLayoutType": "ThreeColumnsEndExpanded"
            }
        },
                      "pages": [{
                               "entitySet": "…",
                               "component": {
                                     "name": "sap.suite.ui.generic.template.ListReport",
                                     "settings": {
                                              …
                                       }
                                 },
                                  "pages": [{
                                            "entitySet": "…",
                                             "defaultLayoutType": "OneColumn",
                                             "component": {
                                                      "name": "sap.suite.ui.generic.template.ObjectPage",
                                                      "settings": {
                                                                 …
                                                      }
                                             },
```

**STEP**: 5 — Enable FCL in manifest.json (OData V4) — add rootView

**DESCRIPTION**: For OData V4 FE apps, add the rootView to sap.ui5 in manifest.json to use FCL root view (sap.fe.core.rootView.Fcl). This is required to enable FCL instead of full-screen.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.ui5":{
 …
        "rootView":{
            "viewName":"sap.fe.core.rootView.Fcl",
            "type":"XML",
            "async":true,
            "id":"appRootView"
        },
…
   }
```

**STEP**: 6 — Enable FCL in manifest.json (OData V4) — routerClass + flexibleColumnLayout in routing config

**DESCRIPTION**: Set routerClass to sap.f.routing.Router and add flexibleColumnLayout defaults under the "routing" → "config" key. Ensure the sap.f library is added as a dependency under sap.ui5.

**LANGUAGE**: JSON

**CODE**:
```json
"routing":{
     "config":{
            "routerClass":"sap.f.routing.Router",
            "flexibleColumnLayout":{
                    "defaultTwoColumnLayoutType":"TwoColumnsMidExpanded",
                    "defaultThreeColumnLayoutType":"ThreeColumnsMidExpanded"
                }
            },
           "routes":[
              …
            ]
    }
```

**STEP**: 7 — Configure routes for FCL (OData V4) — general rules

**DESCRIPTION**: For FCL routing:
- route.pattern: pattern to match navigation (end with :?query: if required).
- route.name: unique route identifier.
- route.target: ARRAY listing the targets to display for the route (controls number/placement of columns).

Targets map to control aggregations:
- beginColumnPages → first column
- midColumnPages → second column
- endColumnPages → third column

Use sap.fe.templates.ListReport for first-level view and sap.fe.templates.ObjectPage for subsequent levels.

**LANGUAGE**: none

**CODE**:
```text
Routing keys to set:
- name: unique route id
- target: array of target names to display (controls how many columns populate)
Targets: each target sets controlAggregation (beginColumnPages | midColumnPages | endColumnPages)
```

**STEP**: 8 — Sample: 3-column layout starting with List Report (OData V4)

**DESCRIPTION**: Scenario: List report → List report | Object page 1 → List report | Object page 1 | Object page 2 → Object page 3. The routes define the target arrays to load 1, 2 or 3 columns.

Place these route and target fragments inside manifest.json routing and targets sections.

**LANGUAGE**: JSON

**CODE**:
```json
"routes": [
     	{
        	"pattern": ":?query:",
            "name": "SalesOrderManageList",
            "target": ["SalesOrderManageList"]
        },
        {
        	"pattern": "SalesOrderManage({key}):?query:",
            "name": "SalesOrderManageObjectPage",
            "target": ["SalesOrderManageList", "SalesOrderManageObjectPage"]
        },
        {
        	"pattern": "SalesOrderManage({key})/_Item({key2}):?query:",
            "name": "SalesOrderItemObjectPage",
            "target": ["SalesOrderManageList", "SalesOrderManageObjectPage", "SalesOrderItemObjectPage"]
         },
         {
         	"pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3}):?query:",
            "name": "MaterialDetailsObjectPage",
            "target": ["MaterialDetailsObjectPage"]
         },
         {
         	"pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})/_MaterialRatings({key4}):?query:",
            "name": "MaterialRatingsObjectPage",
            "target": ["MaterialRatingsObjectPage"]
         },
         {
          	"pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})/_MaterialRatings({key4})/_MaterialRatingsDetails({key5}):?query:",
            "name": "MaterialRatingsDetailsObjectPage",
            "target": ["MaterialRatingsDetailsObjectPage"]
         }
],
"targets": {
   "SalesOrderManageList": {
       "type": "Component",
       "id": "SalesOrderManageList",
       "name": "sap.fe.templates.ListReport",
       "controlAggregation": "beginColumnPages",
       "contextPattern": "",
       "options": {
                ...
       }
   },
   "SalesOrderManageObjectPage": {
       "type": "Component",
       "id":  "SalesOrderManageObjectPage",
       "name": "sap.fe.templates.ObjectPage",
       "controlAggregation": "midColumnPages",
       "contextPattern": "/SalesOrderManage({key})",
       "options": {
                ...
       }
   },
   "SalesOrderItemObjectPage": {
       "type": "Component",
       "id":  "SalesOrderItemObjectPage",
       "name": "sap.fe.templates.ObjectPage",
       "controlAggregation": "endColumnPages",
       "contextPattern": "/SalesOrderManage({key})/_Item({key2})",
       "options": {
                ...
       }
   },
   "MaterialDetailsObjectPage": {
       "type": "Component",
       "id":  "MaterialDetailsObjectPage",
       "name": "sap.fe.templates.ObjectPage",
       "controlAggregation": "endColumnPages",
       "contextPattern": "/SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})",
       "options": {
                ...
       }
   },
   ...
}
```

**STEP**: 9 — Sample: 2-column layout that starts with an Object Page (OData V4)

**DESCRIPTION**: Scenario: List report → Object page 1 → Object page 1 | Object page 2 → Object page 3. Adjust route.target arrays and controlAggregation to move pages between columns.

**LANGUAGE**: JSON

**CODE**:
```json
"routes": [
                {
               "pattern": ":?query:",
               "name": "SalesOrderManageList",
               "target": ["SalesOrderManageList"]
        },
        {
               "pattern": "SalesOrderManage({key}):?query:",
               "name": "SalesOrderManageObjectPage",
               "target": ["SalesOrderManageObjectPage"]
        },
        {
               "pattern": "SalesOrderManage({key})/_Item({key2}):?query:",
               "name": "SalesOrderItemObjectPage",
               "target": ["SalesOrderManageObjectPage", "SalesOrderItemObjectPage"]
         },
         {
               "pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3}):?query:",
               "name": "MaterialDetailsObjectPage",
               "target": ["MaterialDetailsObjectPage"]
         },
        …
],
"targets": {
       "SalesOrderManageList": {
           "type": "Component",
           "id": "SalesOrderManageList",
           "name": "sap.fe.templates.ListReport",
           "controlAggregation": "beginColumnPages",
           "contextPattern": "",
           "options": {
                    ...
           }
       },
       "SalesOrderManageObjectPage": {
           "type": "Component",
           "id":  "SalesOrderManageObjectPage",
           "name": "sap.fe.templates.ObjectPage",
           "controlAggregation": "beginColumnPages",
           "contextPattern": "/SalesOrderManage({key})",
           "options": {
                    ...
           }
       },
       "SalesOrderItemObjectPage": {
           "type": "Component",
           "id":  "SalesOrderItemObjectPage",
           "name": "sap.fe.templates.ObjectPage",
           "controlAggregation": "midColumnPages",
           "contextPattern": "/SalesOrderManage({key})/_Item({key2})",
           "options": {
                    ...
           }
       },
       "MaterialDetailsObjectPage": {
           "type": "Component",
           "id":  "MaterialDetailsObjectPage",
           "name": "sap.fe.templates.ObjectPage",
           "controlAggregation": "endColumnPages",
           "contextPattern": "/SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})",
           "options": {
                    ...
           }
       },
       ...
   }
```

**STEP**: 10 — Sample: 3-column layout starting with an Object Page (OData V4)

**DESCRIPTION**: Scenario demonstrates complex nested navigation with explicit target arrays to populate specific columns.

**LANGUAGE**: JSON

**CODE**:
```json
"routes": [
    {
        "pattern": ":?query:",
        "name": "SalesOrderManageList",
        "target": "SalesOrderManageList"
    },
    {
        "pattern": "SalesOrderManage({key}):?query:",
        "name": "SalesOrderManageObjectPage",
        "target": ["SalesOrderManageObjectPage"]
    },
    {
        "pattern": "SalesOrderManage({key})/_Item({key2}):?query:",
        "name": "SalesOrderItemObjectPage",
        "target": ["SalesOrderItemObjectPage"]
    },
    {
        "pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3}):?query:",
        "name": "MaterialDetailsObjectPage",
        "target": ["SalesOrderItemObjectPage","MaterialDetailsObjectPage"]
    },
    {
        "pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})/_MaterialRatings({key4}):?query:",
        "name": "MaterialRatingsObjectPage",
        "target": ["SalesOrderItemObjectPage","MaterialDetailsObjectPage","MaterialRatingsObjectPage"]
    },
    {
        "pattern": "SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})/_MaterialRatings({key4})/_MaterialRatingsDetails({key5}):?query:",
        "name": "MaterialRatingsDetailsObjectPage",
        "target": ["MaterialRatingsDetailsObjectPage"]
    }
],
"targets": {
    "SalesOrderManageList": {
        "type": "Component",
        "id": "SalesOrderManageList",
        "name": "sap.fe.templates.ListReport",
        "controlAggregation": "beginColumnPages",
        "contextPattern": "",
        "options": {
            ...
        }
    },
    "SalesOrderManageObjectPage": {
        "type": "Component",
        "id": "SalesOrderManageObjectPage",
        "name": "sap.fe.templates.ObjectPage",
        "controlAggregation": "beginColumnPages",
        "contextPattern": "/SalesOrderManage({key})",
        "options": {
            ...
        }
    },
    "SalesOrderItemObjectPage": {
        "type": "Component",
        "id": "SalesOrderItemObjectPage",
        "name": "sap.fe.templates.ObjectPage",
        "controlAggregation": "beginColumnPages",
        "contextPattern": "/SalesOrderManage({key})/_Item({key2})",
        "options": {
           ...
        }
    },
    "MaterialDetailsObjectPage": {
        "type": "Component",
        "id": "MaterialDetailsObjectPage",
        "name": "sap.fe.templates.ObjectPage",
        "controlAggregation": "midColumnPages",
        "contextPattern": "/SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})",
        "options": {
            ...
        }
    },
    "MaterialRatingsObjectPage": {
        "type": "Component",
        "id": "MaterialRatingsObjectPage",
        "name": "sap.fe.templates.ObjectPage",
        "controlAggregation": "endColumnPages",
        "contextPattern": "/SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})/_MaterialRatings({key4})",
        "options": {
            ...
        }
    },
    "MaterialRatingsDetailsObjectPage": {
        "type": "Component",
        "id": "MaterialRatingsDetailsObjectPage",
        "name": "sap.fe.templates.ObjectPage",
        "controlAggregation": "endColumnPages",
        "contextPattern": "/SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})/_MaterialRatings({key4})/_MaterialRatingsDetails({key5})",
        "options": {
            ...
        }
    }
}
},
```

**STEP**: 11 — Targets configuration details (OData V4)

**DESCRIPTION**: For each target set these keys (same as full-screen apps except controlAggregation and contextPattern may differ):

- type: "Component"
- id: unique identifier
- name: template to use: sap.fe.templates.ListReport for the first level; sap.fe.templates.ObjectPage for subsequent levels
- controlAggregation: beginColumnPages | midColumnPages | endColumnPages
- contextPattern: navigation path to bind the target

Use options the same as full-screen template options.

**LANGUAGE**: JSON

**CODE**:
```json
"targets": {
        "SalesOrderManageList": {
            "type": "Component",
            "id": "SalesOrderManageList",
            "name": "sap.fe.templates.ListReport",
            "controlAggregation": "beginColumnPages",
            "contextPattern": "",
            "options": {
                        ...
                     // Same as fullscreen  //
                        ...
            }
        },
        "SalesOrderManageObjectPage": {
            "type": "Component",
            "id":  "SalesOrderManageObjectPage",
            "name": "sap.fe.templates.ObjectPage",
            "controlAggregation": "midColumnPages",
            "contextPattern": "/SalesOrderManage({key})",
            "options": {
                        ...
                     // Same as fullscreen  //
                        ...
            }
        },
        "SalesOrderItemObjectPage": {
            "type": "Component",
            "id":  "SalesOrderItemObjectPage",
            "name": "sap.fe.templates.ObjectPage",
            "controlAggregation": "endColumnPages",
            "contextPattern": "/SalesOrderManage({key})/_Item({key2})",
            "options": {
                        ...
                     // Same as fullscreen  //
                        ...
            }
        },
        "MaterialDetailsObjectPage": {
            "type": "Component",
            "id":  "MaterialDetailsObjectPage",
            "name": "sap.fe.templates.ObjectPage",
            "controlAggregation": "endColumnPages",
            "contextPattern": "/SalesOrderManage({key})/_Item({key2})/_MaterialDetails({key3})",
            "options": {
                         ...
                      // Same as fullscreen  //
                         ...
            }
        },
        ...
    }
```

**STEP**: 12 — Saving column resize information (personalization)

**DESCRIPTION**: Column resize information (sizes adjusted by end users) is saved per application and device type within personalization settings. No extra manifest config required; this is built-in behavior.

**LANGUAGE**: none

**CODE**:
```text
Column resize state persists per application and device (desktop/tablet/phone) in personalization storage.
```

**STEP**: 13 — Known restrictions and notes

**DESCRIPTION**: Keep these constraints in mind when designing FCL-enabled applications:

- Overview page: FCL is not relevant or supported.
- Analytical List Page: supports only TwoColumnsBeginExpanded.
- Both draft and non-draft applications support 2- and 3-column layouts; in non-draft CRUD apps, only the last column shows Edit/Delete buttons.
- In edit mode on an object page, a subobject page closes automatically when you add/remove a column from a table.
- If a list report or object page contains multiple tables based on the same entity, only the first table synchronizes with its subobject page.
- After updating a multi-input field on an object page, refresh the parent page to see changes.
- Tree table and analytical table in the list report cannot be displayed in FCL when using a draft-enabled service.
- For OData V4: ensure the sap.f library is declared as a dependency under sap.ui5.

**LANGUAGE**: none

**CODE**:
```text
Restrictions summary:
- No FCL for Overview Page
- Analytical List Page: only TwoColumnsBeginExpanded
- Only last column shows edit/delete in non-draft CRUD apps
- Subobject pages close if table columns change in edit mode
- Only first table (if multiple on same entity) syncs with subobject page
- Refresh parent page after multi-input updates to see changes
- Tree/Analytical table in list report not supported with draft-enabled service
- For OData V4, add sap.f to sap.ui5 dependencies
```


**TITLE**: Enable Full-Screen Mode for Tables (SAP Fiori elements for OData V4)

**INTRODUCTION**: Enable a full-screen toggle for table controls by adding a manifest.json configuration. This displays a full-screen button on the table toolbar (left of the personalization button) and opens the table in a full-screen dialog with a Close button. Applicable only for SAP Fiori elements for OData V4.

**TAGS**: fiori-elements-framework, manifest.json, odata-v4, table, fullscreen, controlConfiguration, UI.v1.LineItem, tableSettings

**STEP**: 1 — Verify applicability and prerequisites

**DESCRIPTION**: Confirm your application is built with SAP Fiori elements for OData V4. The full-screen table setting:
- Applies only to OData V4 Fiori elements.
- Is ignored if configured for a list report (the templating phase will drop it).
- Is enabled by default on mobile phones (no manifest change needed for mobile).

If your app meets the requirement, proceed to modify manifest.json.

**LANGUAGE**: Text

**CODE**:
```
# Precondition: SAP Fiori elements for OData V4
# Note: Do not apply this setting for list reports (it will be ignored)
```

**STEP**: 2 — Modify manifest.json to enable full-screen for a table

**DESCRIPTION**: Open your application's manifest.json and add the controlConfiguration.tableSettings.enableFullScreen property under the target object's settings. Insert the snippet under the relevant object (for example: SalesOrderManageObjectPage). This exact JSON snippet toggles on the full-screen button for the object's table LineItem.

Place the snippet in manifest.json at the appropriate location for your page (e.g., within the target object's options -> settings -> controlConfiguration -> _Item/@com.sap.vocabularies.UI.v1.LineItem).

**LANGUAGE**: JSON

**CODE**:
```json
"SalesOrderManageObjectPage": {
    "options": {
        "settings": {
            "controlConfiguration": {
                "_Item/@com.sap.vocabularies.UI.v1.LineItem": {
                    "tableSettings": {
                        "enableFullScreen": true
                    }
                }
            }
        }
    }
}
```

**STEP**: 3 — Expected UI behavior and visual references

**DESCRIPTION**: After enabling:
- A full-screen button appears on the table toolbar to the left of the personalization button.
- Clicking the button opens the table in a full-screen dialog; the button icon toggles to allow exiting full-screen.
- A Close button is shown at the bottom of the dialog to exit full-screen mode.

Image references used in the documentation:
- images/Full-Screen_Button_for_Tables_543c2fd.png
- images/Close_Full-Screen_Mode_for_Tables_0d13370.png

Include or reference these images in your documentation or UI guides as needed. No additional runtime configuration is required.


**TITLE**: Enabling the History of Recently Entered Values (SAP Fiori elements)

**INTRODUCTION**: This guide shows how to enable, disable, and configure the input-history (recently entered values) behavior for fields in SAP Fiori elements applications. It covers prerequisites, OData V2 per-field and global settings (manifest.json), OData V4 settings, and security controls to prevent storing sensitive personal data.

**TAGS**: fiori-elements-framework, manifest.json, input-history, historySettings, OData V2, OData V4, security, PersonalData

STEP: Prerequisites
DESCRIPTION: Enable the SAP Fiori launchpad parameter INPUTFIELD_HISTORY so the platform allows storing and showing recently entered values. Verify this setting before changing manifest.json. See Manage Launchpad Settings for details.
LANGUAGE: Link
CODE:
```text
Manage Launchpad Settings:
https://help.sap.com/docs/SAP_S4HANA_CLOUD/4fc8d03390c342da8a60f8ee387bca1a/22d573aead754b80abca18ec71872fb7.html
```

STEP: Configure history per field (OData V2)
DESCRIPTION: In the application's manifest.json, configure historySettings under sap.ui.generic.app → pages → "<PageId>" → component → settings → filterSettings. Use the fields map to set historyEnabled for specific OData property names. Possible values: "enabled", "disabled", "auto" (default). Replace <fieldname> with the OData property name.
LANGUAGE: JSON
CODE:
```json
"sap.ui.generic.app": {
    "pages": {
        "ListReport|RootEntity": {
            "component": {
                "settings": {
                    "filterSettings": {
                        "historySettings": {
                            "fields": {
                                "<fieldname>": {
                                    "historyEnabled": ("enabled" | "disabled" | "auto")
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

STEP: Configure global/default history behavior (OData V2)
DESCRIPTION: Use historySettings.historyEnabled at the filterSettings level to apply a default behavior to all fields or those not explicitly listed. Valid values: "enabled", "disabled", "auto" (default). Place this under the same manifest.json path shown for OData V2 pages.
LANGUAGE: JSON
CODE:
```json
"sap.ui.generic.app": {
    "pages": {
        "ListReport|RootEntity": {
            "component": {
                "settings": {
                    "filterSettings": {
                        "historySettings": {
                            "historyEnabled": (
                                "enabled" |
                                "disabled" |
                                "auto"
                            )
                        }
                    }
                }
            }
        }
    }
}
```

STEP: Configure history per field (OData V4)
DESCRIPTION: For SAP Fiori elements for OData V4, history is enabled by default. To disable history for specific properties, add historySettings under sap.fe in the manifest and set historyEnabled: false for each propertyPath you want to exclude.
LANGUAGE: JSON
CODE:
```json
"sap.fe": {
    "historySettings": {
        "fields": {
            "<propertyPath>": {
                "historyEnabled": false
            }
        }
    }
}
```

STEP: Security — prevent storing sensitive data
DESCRIPTION: To prevent storing potentially sensitive personal data in the history, add the annotation com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive to either:
- the property of the main entity set on which the value help is defined, or
- any ValueList parameter used by the field.

If either the property or any ValueList parameter is annotated with com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive, SAP Fiori elements will not store that field's values in history. Use this to ensure no potentially sensitive information is retained.
LANGUAGE: Annotation
CODE:
```text
Annotation to apply in OData metadata:
com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive
```

STEP: End-user history management and related docs
DESCRIPTION: End users can delete input history from the UI. For UI control behavior and additional information, see the Input History documentation and Configuring Filter Bars.
LANGUAGE: Links
CODE:
```text
Input History:
../10_More_About_Controls/input-history-152f84f.md

Configuring Filter Bars:
configuring-filter-bars-4bd7590.md
```

fiori-elements-framework
manifest.json
input-history
historySettings
OData V2
OData V4
security
PersonalData


**TITLE**: Enabling the Icon for Situation Handling

**INTRODUCTION**: Enable the Situation Handling icon in SAP Fiori elements (OData V4) list reports and object pages by annotating exactly one navigation target entity type with the SAPObjectNodeType = "BusinessSituation". This guide gives the required annotation snippet, verification steps, and UI placement notes for code-generation and service edits.

**TAGS**: fiori-elements-framework, situation-handling, OData V4, annotations, SAPObjectNodeType, SAP Fiori

**STEP**: 1 — Confirm OData V4 and Fiori elements usage

**DESCRIPTION**: Ensure the application is built with SAP Fiori elements for OData V4. The Situation Handling icon support is applicable only for OData V4 services consumed by Fiori elements apps.

**LANGUAGE**: text

**CODE**:
```text
N/A - Confirm your service metadata and UI stack use OData V4 (EDMX v4 / Fiori elements for OData V4).
```

**STEP**: 2 — Add the SAPObjectNodeType annotation to the target entity type

**DESCRIPTION**: In your service metadata or annotations file (EDMX / annotations.xml), add the following annotation to the target entity type that represents business situations. The annotation must be present on the target entity type that a navigation property from the primary entity points to.

- Required annotation Term: com.sap.vocabularies.Common.v1.SAPObjectNodeType
- Required Record Property: Name = "BusinessSituation"
- Place this annotation on the entity type representing the situation nodes.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="com.sap.vocabularies.Common.v1.SAPObjectNodeType">
     <Record>
          <PropertyValue Property="Name" String="BusinessSituation" />
     </Record>
</Annotation>
```

**STEP**: 3 — Ensure exactly one navigation property points to the annotated entity type

**DESCRIPTION**: Your main entity type must contain exactly one NavigationProperty whose Type/Target is the entity type annotated with SAPObjectNodeType (BusinessSituation). Confirm there is only one such navigation property; otherwise the icon will not be shown.

- Action: Add or validate a single NavigationProperty in the main entity metadata that targets the annotated entity type.
- Use consistent names and namespaces in your EDMX/annotations.

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Example navigation property in the main entity type (replace placeholders with your names) -->
<EntityType Name="MainEntityType">
    ...
    <NavigationProperty Name="BusinessSituationNav" Type="Namespace.BusinessSituationEntityType" />
    ...
</EntityType>
```

**STEP**: 4 — Verify UI behavior and image references

**DESCRIPTION**: After deploying the updated metadata/annotations, verify the Situation Handling icon appears:

- In List Reports: next to the first semantic key in a responsive table (or in a dedicated column for non-responsive table types).
- On Object Pages: icon shown next to the semantic key or in a dedicated UI location per Fiori elements behavior.

Reference images used in documentation (for visual verification):
- images/Situation_Handling_in_a_List_Report_8cbabf0.png
- images/Situation_Handling_on_an_Object_Page_3268202.png

**LANGUAGE**: text

**CODE**:
```text
N/A - Validate in the running Fiori elements app that the icon appears as described.
```

fiori-elements-framework
situation-handling
OData V4
annotations
SAPObjectNodeType
SAP Fiori


**TITLE**: Enable List-Detail Mode (Flexible Column Layout) in SAP Fiori Elements

**INTRODUCTION**: Configure the flexible column layout (FCL) to display two columns (list-detail mode) by editing your app's manifest.json. This guide covers both SAP Fiori Elements for OData V2 and OData V4 settings, lists the available parameters and allowed values, and provides exact JSON snippets to place in your manifest.

**TAGS**: fiori-elements-framework, flexible-column-layout, FCL, list-detail, manifest.json, OData V2, OData V4, SAP Fiori

STEP: 1 — Configure List-Detail Mode for SAP Fiori Elements (OData V2)

DESCRIPTION: Edit the app manifest.json under the "sap.ui.generic.app" -> "settings" -> "flexibleColumnLayout" entry. Add or update the parameters below to start the FCL with two columns, limit the maximum number of columns, and configure behavior after deleting an object. Place this block in your manifest.json (project root: manifest.json).

Parameters and allowed values:
- initialColumnsCount: integer — Use to start with two columns. Allowed values: 1 or 2.
- maxColumnsCount: integer — Max number of columns displayed. Allowed values: 2 or 3. If you have three views and set to 2, the third view opens full-screen.
- displayNextObjectAfterDelete: boolean — If true, after deleting a list/main object the next object is displayed. If false, the column is closed. Note: this does not apply when deleting sub-objects within an object page.

LANGUAGE: JSON

CODE:
```json
"sap.ui.generic.app": {
    "_version": "1.1.0",
    "settings": {
        "flexibleColumnLayout": {
            "defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
            "defaultThreeColumnLayoutType": "ThreeColumnsMidExpanded",
            "initialColumnsCount": 2,
            "maxColumnsCount" : 2,
            "displayNextObjectAfterDelete": true
        }
    },
    "pages": [
```

STEP: 2 — Configure List-Detail Mode for SAP Fiori Elements (OData V4)

DESCRIPTION: For OData V4 apps, edit the manifest.json routing configuration. Set the "flexibleColumnLayout" properties under "routing" -> "config". Use limitFCLToTwoColumns to restrict the FCL to two columns. Place this block in your manifest.json (project root: manifest.json).

Parameter and allowed values:
- limitFCLToTwoColumns: boolean — If true, FCL is limited to two columns and a third view opens full-screen. Allowed values: true or false.
- defaultTwoColumnLayoutType / defaultThreeColumnLayoutType: layout presets (examples provided). These define initial expansion state for two- and three-column layouts.

LANGUAGE: JSON

CODE:
```json
"routing": {
    "config": {
        "routerClass": "sap.f.routing.Router",
        "flexibleColumnLayout": {
            "defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
            "defaultThreeColumnLayoutType": "ThreeColumnsMidExpanded",
            "limitFCLToTwoColumns": true
        }
    },
}
```

fiori-elements-framework
flexible-column-layout
FCL
list-detail
manifest.json
OData V2
OData V4
SAP Fiori