**TITLE**: Overriding Back-End Annotations into Local Annotation Files (Fiori Tools)

**INTRODUCTION**: Procedures to copy back-end OData annotations into local annotation files within a Fiori Tools project and to create additional local annotation files using the Annotation File Manager. Use these steps to extend or customize annotation metadata for your UI application.

**TAGS**: fiori-tools, annotations, odata, local-annotations, manifest.json, annotation-file-manager

**STEP**: Overriding Back End Annotations

**DESCRIPTION**:
- Open the back-end annotation details view for the target annotation.
- Click the Copy icon next to the back-end annotation to copy it into a local annotation file. The copy action provides a starting point for extending or customizing annotations.
- If the project has a single local annotation file associated with the service, the annotation is copied automatically to that file.
- If multiple local annotation files for the same service exist, select the desired target file from the dropdown before confirming the copy.
- Notes:
  - You can add multiple local annotation files to a project.
  - You can copy annotations between back-end and local annotation files only in the supported direction: copy backend -> local or copy local -> local. You cannot copy local -> backend.

**LANGUAGE**: HTML

**CODE**:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>

<!-- Copy icon used in the UI view for back-end annotations -->
<span class="SAP-icons-V5"></span>

<!-- Screenshot reference shown in the documentation -->
<img src="images/Overriding_annotations_64a3f74.png" alt="Overriding annotations screenshot"/>
```

**STEP**: Creating Additional Local Annotation Files

**DESCRIPTION**:
- Use the Annotation File Manager to create new local annotation files for an OData service (not supported for CAP CDS).
- Procedure:
  1. Right-click the manifest.json file in the project and select "Open Annotation File Manager".
  2. Click "Create Local Annotation File".
  3. Enter the new file name, the XML namespace, and choose the folder location within the project.
  4. Click "Create" to generate the local annotation file and associate it with the service.
- File creation constraints:
  - Additional annotation files can only be created for OData services (not CAP CDS).
  - After creation, use the Annotation File Manager or the language server (see "Maintaining Annotations with Language Server") to edit and maintain annotations.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "manifest": "manifest.json",
  "annotationFileCreationSteps": [
    "Right-click manifest.json -> Open Annotation File Manager",
    "Click 'Create Local Annotation File'",
    "Enter: file name, namespace, folder",
    "Click 'Create'"
  ],
  "note": "Additional annotation files can only be created for an OData service, not CAP CDS."
}
```

fiori-tools annotations odata local-annotations manifest.json annotation-file-manager


**TITLE**: Overview of features in generated Fiori projects

**INTRODUCTION**: This document lists and links the key features included in projects generated by the fiori-tools generator. Use the linked documentation files to implement, configure, or troubleshoot each feature in your generated project.

**TAGS**: fiori-tools, SAP Fiori, project-generation, annotation-support, taskbar-notification, edit-in-source, automatic-generation, i18n, project-cleanup

**STEP**: 1 — Annotation Support

**DESCRIPTION**: Read and apply the Annotation Support guidance to enable or customize OData annotation handling in generated projects. Use this when you need model-driven UI elements, metadata annotations, or to extend annotation processing.

**LANGUAGE**: Markdown

**CODE**:
```markdown
[Annotation Support](annotation-support-796f6a4.md)
```

**STEP**: 2 — Taskbar Notification

**DESCRIPTION**: Follow the Taskbar Notification documentation to enable desktop taskbar notifications or in-app notifications integrated with the generated app. Use this to notify users of background tasks, updates, or long-running operations.

**LANGUAGE**: Markdown

**CODE**:
```markdown
[Taskbar Notification](taskbar-notification-c66373a.md)
```

**STEP**: 3 — Edit in Source Code

**DESCRIPTION**: Use the Edit in Source Code guide to open, modify, and persist generated UI or controller code. This is required when customizing generated artifacts beyond declarative configuration.

**LANGUAGE**: Markdown

**CODE**:
```markdown
[Edit in Source Code](edit-in-source-code-7d8e942.md)
```

**STEP**: 4 — Automatic Generation

**DESCRIPTION**: Refer to Automatic Generation to understand the scaffolding process, templates used, and how to re-run or customize the generator for regeneration of project artifacts.

**LANGUAGE**: Markdown

**CODE**:
```markdown
[Automatic Generation](automatic-generation-576f9fe.md)
```

**STEP**: 5 — Internationalization (i18n)

**DESCRIPTION**: Follow the Internationalization (i18n) documentation to add or modify translations, resource bundles, and locale handling within the generated project. Use this for multi-language support and locale-specific formatting.

**LANGUAGE**: Markdown

**CODE**:
```markdown
[Internationalization (i18n)](internationalization-i18n-eb427f2.md)
```

**STEP**: 6 — Project Cleanup

**DESCRIPTION**: Use Project Cleanup instructions to remove unnecessary files, apply best-practice folder structure, and clean up generated placeholders before committing or deploying the project.

**LANGUAGE**: Markdown

**CODE**:
```markdown
[Project Cleanup](project-cleanup-2640899.md)
```

fiori-tools
SAP Fiori
project-generation
annotation-support
taskbar-notification
edit-in-source
automatic-generation
i18n
project-cleanup


**TITLE**: Peek and Go To Definition for Annotation References

**INTRODUCTION**: This document explains how to use Peek Definition and Go To Definition to preview, navigate to, and update annotation sources while editing annotation references or translatable string values. Use these actions when your cursor is inside a referenced annotation value or a path that references an annotation term segment.

**TAGS**: fiori-tools, annotations, peek-definition, go-to-definition, vscode, sap-business-application-studio, navigation, editor-shortcuts

**STEP**: Peek Definition — trigger and behavior

**DESCRIPTION**: Preview and edit the referenced annotation inline (without switching tabs). Place the text cursor inside the referenced annotation value or path segment and use one of the triggers below. If the annotation is defined in multiple sources, a list of sources is shown; select one to open the inline preview. Note: annotation layering is not considered.

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Place the text cursor (|) inside the annotation reference value below -->
<PropertyValue Property="Value" Path="@UI.LineItem/0/Label|"/>
```

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Place the cursor inside a translatable string value -->
<Annotation Term="UI.HeaderInfo">
  <Record>
    <PropertyValue Property="Title" String="Sales Order |"/>
  </Record>
</Annotation>
```

**STEP**: Peek Definition — triggers (actions to implement in code generators)

**DESCRIPTION**: Implement editor integrations that call the inline preview action when the caret is inside an annotation reference or translatable string. Provide these triggers:

- Windows: Alt + F12
- macOS: Option (Alt) + F12
- Mouse: right-click → "Peek Definition"

Ensure the inline pane allows editing and saving back to the selected source file.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "peekDefinitionTriggers": {
    "windows": "Alt+F12",
    "macos": "Option+F12",
    "contextMenu": "RightClick -> Peek Definition"
  },
  "behavior": "Show inline preview/editor. If multiple sources exist, list and allow selection. Annotation layering not considered."
}
```

**STEP**: Go To Definition — trigger and behavior

**DESCRIPTION**: Jump to the annotation source file and open it in a new editor tab scrolled to the exact annotation location. Place the text cursor inside the path referencing the annotation term segment or inside the translatable string value and use one of the triggers below. If the annotation is defined in multiple sources, show the Peek Definition listing instead.

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Place the cursor (|) inside the reference to trigger Go To Definition -->
<PropertyValue Property="Value" Path="@com.example.vocabularies.UI.v1.LineItem/0/Label|"/>
```

**STEP**: Go To Definition — triggers (actions to implement in code generators)

**DESCRIPTION**: Implement editor integrations that navigate to the definition location when the caret is inside the annotation reference. Provide these triggers:

- Visual Studio Code: F12
- SAP Business Application Studio: Ctrl + F11
- Mouse context menu: right-click → "Go To Definition"
- Modifier + click:
  - Windows: Ctrl + click
  - macOS: Cmd + click

Open the source file in a new tab and scroll to the annotation location. If multiple sources exist, present the Peek Definition list instead of directly navigating.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "goToDefinitionTriggers": {
    "vscode": "F12",
    "sap_bas": "Ctrl+F11",
    "contextMenu": "RightClick -> Go To Definition",
    "modifierClick": {
      "windows": "Ctrl + Click",
      "macos": "Cmd + Click"
    }
  },
  "behavior": "Open source file in new tab at exact annotation location. If multiple sources exist, show Peek Definition list. Annotation layering not considered."
}
```

fiori-tools annotations peek-definition go-to-definition vscode sap-business-application-studio navigation editor-shortcuts


**TITLE**: Progress Column — Add, Move, and Delete in Fiori Tools Page Editor

**INTRODUCTION**: This guide describes how to add a Progress Column (UI.DataPoint + UI.LineItem DataFieldForAnnotation) to a table/section in the Fiori Tools Page Editor, how the annotation is created and what default values are set, how to move the column within a table, and how to delete it. Use the examples to generate or modify annotation XML and to implement editor automation.

**TAGS**: fiori-tools, SAP Fiori, progress column, UI.DataPoint, UI.LineItem, annotations, micro charts

**STEP**: Add Progress Column

**DESCRIPTION**: Add a Progress Column to a table/section via the Page Editor. The editor creates a UI.DataPoint annotation and a UI.LineItem entry (UI.DataFieldForAnnotation) that references the DataPoint. Default property values set by the editor: Value = chosen numeric property, TargetValue = 100, Visualization = Progress. If the table/entity has no numeric properties or they are all already used in the table, the Add Progress Column option is disabled.

Action steps (user flow):
- Click the + (Add) icon in the Columns node in the Page Editor and choose Add Progress Column.
- Select the property to use as the Value.
- The editor creates the UI.DataPoint and updates UI.LineItem with a UI.DataFieldForAnnotation referencing the DataPoint and a generated Label.

Preserve these anchors/links for additional property references:
- Label: appendix-457f2e9.md#loiod44832d99bdf4f73ba14cdbb16dc9301
- Importance: appendix-457f2e9.md#loio7fe32a215209419da6d6c19da0f69ccb
- Hidden: appendix-457f2e9.md#loiof7ad71792a0044d6b6172f078827bdc0
- Target Type: appendix-457f2e9.md#loio678bf9265c664134a075b59fd193c64e
- Target: appendix-457f2e9.md#loio7fba03aba4214ceab2130f16186f4ff2
- Criticality for Micro Charts and Progress Indicators: appendix-457f2e9.md#loio19d82b5d8bc940738afcb49b51a48bed__section_xdw_kkj_kfc
- Tooltip Source: appendix-457f2e9.md#loiof0bc466aae5b42e697c89506026050af

**LANGUAGE**: HTML

**CODE**:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Example annotation created by Page Editor when adding a Progress Column -->
<Annotations Target="YourService.YourEntityType">
  <!-- DataPoint for progress -->
  <Annotation Term="UI.DataPoint" Qualifier="Progress1">
    <Record>
      <!-- Value: user-selected numeric property -->
      <PropertyValue Property="Value" Path="ProgressProperty"/>
      <!-- TargetValue: default 100 -->
      <PropertyValue Property="TargetValue" Int="100"/>
      <!-- Visualization: Progress -->
      <PropertyValue Property="Visualization" EnumMember="UI.VisualizationType/Progress"/>
    </Record>
  </Annotation>

  <!-- LineItem updated with DataFieldForAnnotation referencing the DataPoint -->
  <Annotation Term="UI.LineItem">
    <Collection>
      <Record Type="UI.DataFieldForAnnotation">
        <!-- Generated label based on selected property -->
        <PropertyValue Property="Label" String="ProgressProperty"/>
        <!-- Reference to the DataPoint annotation -->
        <PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Progress1"/>
      </Record>
      <!-- other line items... -->
    </Collection>
  </Annotation>
</Annotations>
```

**STEP**: Progress Column Properties (post-creation)

**DESCRIPTION**: After the Progress Column is added, the editor exposes these configurable properties. Use these anchors to programmatically read or set values in the annotation or UI metadata.

- Label — appendix-457f2e9.md#loiod44832d99bdf4f73ba14cdbb16dc9301
- Importance — appendix-457f2e9.md#loio7fe32a215209419da6d6c19da0f69ccb
- Hidden — appendix-457f2e9.md#loiof7ad71792a0044d6b6172f078827bdc0
- Target Type — appendix-457f2e9.md#loio678bf9265c664134a075b59fd193c64e
- Target — appendix-457f2e9.md#loio7fba03aba4214ceab2130f16186f4ff2
- Criticality (micro charts & progress indicators) — appendix-457f2e9.md#loio19d82b5d8bc940738afcb49b51a48bed__section_xdw_kkj_kfc
- Tooltip Source — appendix-457f2e9.md#loiof0bc466aae5b42e697c89506026050af

**LANGUAGE**: N/A

**CODE**:
```text
// No code block; use the annotation XML above to set/update these properties.
```

**STEP**: Move Progress Column within a Table

**DESCRIPTION**: Reorder the Progress Column inside a table using either Drag and Drop (multi-column support) or Arrow Icons (single-column, stepwise).

- Drag and Drop:
  - Hover over the table column outline, press and hold the mouse button, drag to the desired position (eligible drop positions are highlighted in green), and release.
  - To move multiple columns at once, use keyboard modifier: press Ctrl + + while performing the drag-and-drop operation.

- Arrow Icons:
  - Click the Move Up () or Move Down () icon next to the column name in the Page Editor to move the column one position up or down. This moves only one column at a time.

**LANGUAGE**: N/A

**CODE**:
```text
// UI interactions; no code to generate. Implement editor automation to call the table column reorder routine
// or update UI.LineItem Collection ordering in the annotations XML to reflect new column order.
```

**STEP**: Delete Progress Column

**DESCRIPTION**: Remove the Progress Column via the Page Editor. This deletes the UI.LineItem entry referencing the DataPoint and may optionally remove the UI.DataPoint annotation if unused.

Action steps:
1. Navigate to the column in the Columns tree.
2. Click the Delete (wastebasket) icon to open the Delete Confirmation dialog.
3. Click Delete to confirm removal.

Implementation note: When automating deletion, remove the UI.DataFieldForAnnotation record from UI.LineItem and consider removing the corresponding UI.DataPoint if it has no other references.

**LANGUAGE**: N/A

**CODE**:
```text
// Pseudocode for automation:
// 1. Locate UI.LineItem Collection in annotations for the entity.
// 2. Remove DataFieldForAnnotation element where Target references @UI.DataPoint#ProgressQualifier.
// 3. If no remaining references to @UI.DataPoint#ProgressQualifier, remove the UI.DataPoint annotation.
```

fiori-tools
SAP Fiori
progress column
UI.DataPoint
UI.LineItem
annotations
micro charts


**TITLE**: Project Cleanup — Remove Orphaned UI Annotations

**INTRODUCTION**: This document describes a deterministic cleanup procedure for Fiori Tools projects. The cleanup removes orphaned UI annotations (UI.FieldGroup, UI.LineItem) that are not referenced by UI.ReferenceFacet targets, and removes property-level annotations using specific terms when those properties are not referenced anywhere by remaining annotations. Use this procedure in build tools or RAG-based code generators to automatically prune unused annotations from OData annotation files (XML or JSON).

**TAGS**: fiori-tools, cleanup, annotations, UI.FieldGroup, UI.LineItem, UI.ReferenceFacet, OData, TypeScript

STEP: 1 — Gather annotation files and parse them

DESCRIPTION: Read all annotation files in the project (XML or JSON). Parse them into an in-memory representation that allows walking annotation elements and terms. Use a parser that supports OData annotation XML (EDMX/Annotations) and JSON annotation formats.

LANGUAGE: TypeScript

CODE:
```typescript
// Example: collect all annotation files and parse XML/JSON into an AST-like structure.
// Requires: npm install fast-xml-parser glob fs-extra
import { readFile } from 'fs/promises';
import { parse as parseXml } from 'fast-xml-parser';
import glob from 'glob';

async function loadAnnotationFiles(projectRoot: string) {
  const patterns = ['**/*.annotations.xml', '**/*.xml', '**/*.annotations.json', '**/*.json'];
  const files = patterns.flatMap(pattern => glob.sync(pattern, { cwd: projectRoot, absolute: true }));
  const contents = await Promise.all(files.map(async f => ({ path: f, text: await readFile(f, 'utf8') })));
  return contents.map(c => {
    const isJson = c.path.endsWith('.json');
    return {
      path: c.path,
      format: isJson ? 'json' : 'xml',
      ast: isJson ? JSON.parse(c.text) : parseXml(c.text, { ignoreAttributes: false, attributeNamePrefix: '@_' })
    };
  });
}
```

STEP: 2 — Collect referenced UI.ReferenceFacet targets

DESCRIPTION: Walk all parsed annotation ASTs and collect targets referenced by UI.ReferenceFacet. These targets define which facets/annotations are actually used by the UI. Normalize target strings to the canonical form used in your annotation files (e.g., "EntityType/AnnotationName" or "Namespace.Type/Annotations").

LANGUAGE: TypeScript

CODE:
```typescript
// Example: extract all targets referenced by UI.ReferenceFacet in parsed ASTs.
// This sample assumes the XML parse resulted in an object model where annotation elements
// include term names and attributes like Target or Path.
function collectReferenceFacetTargets(parsedFiles: { path: string; format: string; ast: any }[]) {
  const targets = new Set<string>();
  for (const file of parsedFiles) {
    const root = file.ast;
    // Walk AST to find UI.ReferenceFacet occurrences. Implementation depends on your parser output.
    // Example for xml->object where elements appear under "Annotations" -> "Annotation" etc.
    function walk(node: any) {
      if (!node || typeof node !== 'object') return;
      for (const [k, v] of Object.entries(node)) {
        if (k.includes('ReferenceFacet') || (Array.isArray(v) && v.some((e: any) => e?.['@_Term']?.endsWith('UI.ReferenceFacet')))) {
          if (Array.isArray(v)) {
            for (const item of v) {
              const t = item['@_Target'] || item['Target'] || item['@_Term'] || item.Target;
              if (t) targets.add(String(t));
            }
          }
        }
        if (typeof v === 'object') walk(v);
      }
    }
    walk(root);
  }
  return targets;
}
```

STEP: 3 — Detect orphaned UI.FieldGroup and UI.LineItem annotations

DESCRIPTION: Find all UI.FieldGroup and UI.LineItem annotation elements. For each element, check whether its annotation target is included in the ReferenceFacet targets set. If not referenced, mark the element for removal.

LANGUAGE: TypeScript

CODE:
```typescript
// Example detection: returns list of file paths and element locations to remove.
// This example assumes each annotation element has a Target attribute or can be identified by path.
function findOrphanedFieldGroupsAndLineItems(parsedFiles: { path: string; ast: any }[], referenceTargets: Set<string>) {
  const orphaned: { path: string; element: any; term: string; target: string }[] = [];
  for (const file of parsedFiles) {
    function walk(node: any, parent?: any) {
      if (!node || typeof node !== 'object') return;
      for (const [k, v] of Object.entries(node)) {
        // Check UI.FieldGroup or UI.LineItem terms in keys or attributes
        if (k.includes('FieldGroup') || k.includes('LineItem') || (Array.isArray(v) && v.some((e: any) => e?.['@_Term']?.includes('UI.FieldGroup') || e?.['@_Term']?.includes('UI.LineItem')))) {
          const items = Array.isArray(v) ? v : [v];
          for (const item of items) {
            const target = item['@_Target'] || item.Target || item['@_Path'] || item.Path || '';
            const term = item['@_Term'] || item['Term'] || k;
            if (!referenceTargets.has(target)) {
              orphaned.push({ path: file.path, element: item, term, target });
            }
          }
        }
        if (typeof v === 'object') walk(v, node);
      }
    }
    walk(file.ast);
  }
  return orphaned;
}
```

STEP: 4 — Identify property-level annotations to remove

DESCRIPTION: Identify annotations applied to entity properties using any of these terms:
- UI.MultiLineText
- Common.ValueListWithFixedValues
- Common.Text
- Common.ValueList
- Common.FieldControl

For each such property annotation, check whether the property is referenced in any referenced annotations (e.g., in UI.ReferenceFacet targets, UI.LineItem Field paths, UI.FieldGroup property references). If the property is not mentioned anywhere by referenced annotations, mark it for removal.

LANGUAGE: TypeScript

CODE:
```typescript
// Example: detect property-level annotations for the listed terms and mark if unreferenced.
const PROPERTY_TERMS = new Set([
  'UI.MultiLineText',
  'Common.ValueListWithFixedValues',
  'Common.Text',
  'Common.ValueList',
  'Common.FieldControl'
]);

function findUnreferencedPropertyAnnotations(parsedFiles: { path: string; ast: any }[], referencedProperties: Set<string>) {
  const toRemove: { path: string; propertyPath: string; term: string; node: any }[] = [];
  for (const file of parsedFiles) {
    function walk(node: any) {
      if (!node || typeof node !== 'object') return;
      for (const [k, v] of Object.entries(node)) {
        if (Array.isArray(v)) {
          for (const item of v) {
            const term = item?.['@_Term'] || item?.Term || '';
            if (PROPERTY_TERMS.has(term)) {
              const propertyPath = item['@_Path'] || item.Path || item['@_Property'] || '';
              if (propertyPath && !referencedProperties.has(propertyPath)) {
                toRemove.push({ path: file.path, propertyPath, term, node: item });
              }
            }
            if (typeof item === 'object') walk(item);
          }
        } else if (typeof v === 'object') {
          walk(v);
        }
      }
    }
    walk(file.ast);
  }
  return toRemove;
}
```

STEP: 5 — Remove marked elements and write back files

DESCRIPTION: For each marked annotation element (orphaned field groups/line items and unreferenced property annotations), remove it from the AST and serialize the AST back to the original file format (XML or JSON). Preserve file encoding and formatting where possible.

LANGUAGE: TypeScript

CODE:
```typescript
// Example: naive removal and write-back. For XML, convert AST back to XML (use fast-xml-parser j2x or a dedicated writer).
import { writeFile } from 'fs/promises';
import { j2xParser as J2xParser } from 'fast-xml-parser';

async function removeAndWrite(parsedFiles: { path: string; format: string; ast: any }[], removals: { path: string; predicate: (node: any) => boolean }[]) {
  for (const file of parsedFiles) {
    // Remove nodes matching any predicate for this file
    function walkAndFilter(node: any, parent?: any, key?: string) {
      if (!node || typeof node !== 'object') return;
      for (const [k, v] of Object.entries(node)) {
        if (Array.isArray(v)) {
          node[k] = v.filter(item => !removals.some(r => r.path === file.path && r.predicate(item)));
          for (const item of node[k]) walkAndFilter(item, node, k);
        } else if (typeof v === 'object') {
          walkAndFilter(v, node, k);
        }
      }
    }
    walkAndFilter(file.ast);

    // Serialize back
    if (file.format === 'json') {
      await writeFile(file.path, JSON.stringify(file.ast, null, 2), 'utf8');
    } else {
      const j2x = new J2xParser({ ignoreAttributes: false, attributeNamePrefix: '@_' });
      const xml = j2x.parse(file.ast);
      await writeFile(file.path, xml, 'utf8');
    }
  }
}
```

STEP: 6 — Validation and safety

DESCRIPTION: Before permanently deleting annotations:
- Produce a dry-run report listing all elements that would be removed (file paths, terms, targets, property paths).
- Optionally back up original annotation files.
- Validate resulting annotations (schema/EDMX validation or run UI runtime checks) to ensure nothing critical was removed.

LANGUAGE: TypeScript

CODE:
```typescript
// Example: produce a dry-run report
function dryRunReport(orphanedFieldGroups: any[], unreferencedProperties: any[]) {
  return {
    orphanedFieldGroups: orphanedFieldGroups.map(o => ({ file: o.path, term: o.term, target: o.target })),
    unreferencedProperties: unreferencedProperties.map(u => ({ file: u.path, propertyPath: u.propertyPath, term: u.term }))
  };
}
```

STEP: 7 — Summary of removal rules (explicit)

DESCRIPTION: Apply the following explicit rules in implementation:
- Remove UI.FieldGroup and UI.LineItem annotation nodes that are not referenced as targets by any UI.ReferenceFacet.
- Remove annotations that use any of these terms when applied to entity properties that are not referenced anywhere by the set of referenced annotations:
  - UI.MultiLineText
  - Common.ValueListWithFixedValues
  - Common.Text
  - Common.ValueList
  - Common.FieldControl

LANGUAGE: Plain text

CODE:
```text
Removal rules:
- Orphan UI nodes: UI.FieldGroup, UI.LineItem -> remove if not referenced by UI.ReferenceFacet targets.
- Property annotations to remove when unreferenced:
  * UI.MultiLineText
  * Common.ValueListWithFixedValues
  * Common.Text
  * Common.ValueList
  * Common.FieldControl
```

Step: Implementation notes

DESCRIPTION: Use the provided TypeScript snippets as templates. Adapt parsing and AST traversal logic to your project's annotation format. Ensure normalization of target/property paths so comparisons correctly detect references (qualifiers, namespace prefixes, and annotation path forms must match). Always run a dry-run and backup before final write-back.

LANGUAGE: Plain text

CODE:
```text
Notes:
- Annotation format differences (EDMX XML vs. JSON) require tailored parsing and serialization.
- Normalize targets and property paths (e.g., EntityType/Property or Namespace.Type/Annotations) before membership checks.
- Provide dry-run and backup options to avoid accidental data loss.
```


**TITLE**: Rating Column — Add, Move, and Delete (Fiori Tools)

**INTRODUCTION**: Instructions and code examples for adding a rating column to a Fiori list report table or object page section, including the exact annotation created, how to move columns within the table, and how to delete a rating column. Use these steps when authoring pages in the Page Editor or when creating annotation XML manually.

**TAGS**: fiori-tools, rating, UI.DataPoint, annotation, table, list-report, object-page, sap-icons

**STEP**: 1 — Include SAP icons stylesheet (if icon classes are used)

**DESCRIPTION**: Ensure the SAP icons stylesheet is available in your editor or HTML page so icon classes (used in the Page Editor UI and examples) render correctly. Keep the relative path as in your project.

**LANGUAGE**: HTML

**CODE**:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

**STEP**: 2 — Add a Rating Column via Page Editor

**DESCRIPTION**: Use the Page Editor Columns node to add a rating column to a table or section. This creates a UI.DataPoint annotation with the required properties. Follow the UI steps:
- Click "Add Rating Columns" from the + (Add) icon in the Columns node.
- Select the target Columns node using the tree control.
- Click Add. The editor creates a UI.DataPoint annotation with:
  - Value: bound to the property you chose (replace PropertyName).
  - TargetValue: set to 5.
  - Visualization: set to enum value Rating.

Also available column properties you can set afterward:
- Label (see appendix-457f2e9.md#loiod44832d99bdf4f73ba14cdbb16dc9301)
- Importance (appendix-457f2e9.md#loio7fe32a215209419da6d6c19da0f69ccb)
- Hidden (appendix-457f2e9.md#loiof7ad71792a0044d6b6172f078827bdc0)
- Target Value (appendix-457f2e9.md#loioa9654b0fd63443d9b2727d1a497f84b6)
- Tooltip Source (appendix-457f2e9.md#loiof0bc466aae5b42e697c89506026050af)

If you author annotations manually, add a DataPoint annotation like the XML example below. Replace Target and Path values to match your entity/property names.

**LANGUAGE**: XML

**CODE**:
```xml
<!-- Example OData annotation (replace Target and PropertyName accordingly) -->
<Annotations Target="YourService.YourEntityType">
  <Annotation Term="com.sap.vocabularies.UI.v1.DataPoint">
    <Record>
      <!-- Value bound to the data property chosen by the user -->
      <PropertyValue Property="Value" Path="PropertyName"/>
      <!-- TargetValue default set to 5 -->
      <PropertyValue Property="TargetValue" Int="5"/>
      <!-- Visualization set to Rating -->
      <PropertyValue Property="Visualization" EnumMember="UI.VisualizationType/Rating"/>
    </Record>
  </Annotation>
</Annotations>
```

**STEP**: 3 — Move Rating Column within a Table

**DESCRIPTION**: Reorder columns in the table using either drag-and-drop or arrow controls in the Page Editor UI.

Options:
- Drag and Drop: Hover the column header, press and hold the mouse button, move the column to the desired highlighted position (eligible positions show in green), and release. To move multiple selected columns at once, hold Ctrl while selecting columns and drag.
- Arrow Icons: Use the Move Up (icon) or Move Down (icon) next to the column name in the Columns node to shift a single column one position at a time.

**LANGUAGE**: Text

**CODE**:
```text
Drag and Drop:
- Hover column outline -> mouse down -> move to highlighted position -> release
- To move multiple columns: select multiple (Ctrl+click) then drag

Arrow Icons:
- Click Move Up () or Move Down () next to the column name (moves one column at a time)
```

**STEP**: 4 — Delete a Rating Column

**DESCRIPTION**: Remove a rating column via the Page Editor Columns node.

Steps:
1. Navigate to the column in the Columns node.
2. Click the Delete (wastebasket) icon to open the Delete Confirmation popup.
3. Click Delete in the popup to confirm and remove the column (this removes the corresponding annotation).

**LANGUAGE**: Text

**CODE**:
```text
Delete steps:
1. Select column in Columns node
2. Click 🗑 (Delete) icon -> Delete Confirmation dialog appears
3. Click Delete to confirm removal of the column and its annotation
```

fiori-tools rating UI.DataPoint annotation table list-report object-page sap-icons


**TITLE**: Request a New Guide

**INTRODUCTION**: Instructions for requesting a new guided development guide in the Fiori tools extension. Includes all entry points to open the Request Guide form, the form fields and submission flow, and reference links and assets.

**TAGS**: fiori-tools, guided-development, guide-request, SAP-Fiori-elements, extension, documentation

**STEP**: 1 — Entry points to open the Request Guide form

**DESCRIPTION**: Use one of these entry points in the Fiori tools guided development extension to open the Request Guide form.

**LANGUAGE**: text

**CODE**:
```text
- Scroll to the bottom of the guides list and click "Request Guide" in the "Don't have what you are looking for?" section.
- Enter "request guide" into the Search guides field.
- Hover over the Help icon (SAP icon glyph) and select "Request New Guide" from the drop-down list.
- Use the Command Palette entry: Fiori: Request New Guide
```

**STEP**: 2 — Help icon and icons stylesheet

**DESCRIPTION**: The Help icon uses SAP icon styles. If you need the icon resources in local documentation or extension HTML, include the sap-icons stylesheet. The guided development UI includes a visual "HELP" icon; the same SAP icons stylesheet reference is used by the extension.

**LANGUAGE**: HTML

**CODE**:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

**STEP**: 3 — INFORMATION panel useful links visual reference

**DESCRIPTION**: From the INFORMATION panel, under the USEFUL LINKS section, choose "Guide Requests for Guided Development". The panel includes a screenshot asset used in docs; keep the image asset path for reference or inclusion.

**LANGUAGE**: HTML

**CODE**:
```html
<img src="images/Fiori_Tools_Guide_Requests_for_Guided_Development_4f9571c.png" alt="Guide Requests for Guided Development"/>
```

**STEP**: 4 — Fill and submit the Request Guide form

**DESCRIPTION**: Complete the Request Guide form fields, submit, and send the generated email. Follow these exact actions to ensure the request is delivered:

- Fill in these fields:
  - Name (your full name)
  - Email (your contact email)
  - Title (brief title for the new guide)
  - Description (detailed description of the feature or guide requested)
- Click Submit.
- An email client will open with a pre-populated message. Check the message content, adjust if required, then click Send in your email client.

**LANGUAGE**: text

**CODE**:
```text
Form fields:
- Name: [Your full name]
- Email: [Your email address]
- Title: [Short guide title]
- Description: [Detailed request / what you need]

Buttons:
- Submit -> opens default email client with composed message
- After email client opens: Review message -> Click Send
```

**STEP**: 5 — Reference documentation link

**DESCRIPTION**: For more information about available features in SAP Fiori elements applications, reference the official documentation.

**LANGUAGE**: text

**CODE**:
```text
Developing Apps with SAP Fiori elements:
https://ui5.sap.com/#/topic/03265b0408e2432c9571d6b3feb6b1fd
```

Request a New Guide

fiori-tools guided-development guide-request SAP-Fiori-elements extension documentation


**TITLE**: Search and Filter Guides in Guided Development (fiori-tools)

**INTRODUCTION**: This document explains how to find, group, filter, and search the list of guided development guides in fiori-tools. Use these steps to programmatically or interactively narrow the available guides by project relevance, page type, OData version, application artifact, annotation type, tags, and free-text search. Includes UI strings and the CSS reference used for icons.

**TAGS**: fiori-tools, guided-development, search, filters, annotations, OData, SAPUI5, UI5, manifest, flex, lines

STEP: 1 - Include icons stylesheet

DESCRIPTION: Ensure the SAP icons stylesheet is referenced so UI icon classes render correctly. Keep the relative path as shown in the guided-development UI.

LANGUAGE: HTML

CODE:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

STEP: 2 - Group by options

DESCRIPTION: Group the guides list by one of three dimensions. Use the correct grouping to surface guides relevant to the current project context.

- Page Type: Group by page/template type. A guide can appear in multiple page type groups; when a multi-page-type guide is selected, the guide relevant to the current project page type is highlighted.
- OData Version: Group by OData service version (V2 vs V4). If a guide is not available for the current OData version, show a version warning.
  Tip: Some guides are available for both OData V2 and V4 but instructions can differ.
- Application Artifacts: Group by the artifact the guide changes: Manifest Change, Flex Change, or Annotations.

Annotations-specific grouping:
- XML Annotation
- CAP CDS Annotation
- ABAP CDS Annotation

Tip: Some guides span multiple annotation types; parameters and code snippets differ per annotation type.

LANGUAGE: TEXT

CODE:
```text
Group by options: Page Type, OData Version, Application Artifacts
Annotation categories: XML Annotation, CAP CDS Annotation, ABAP CDS Annotation
Tip: Guides available for multiple OData/annotation types may contain different instructions per type.
```

STEP: 3 - Default view and how to change it

DESCRIPTION: By default, only guides relevant to the current project are shown. Use the View dropdown to switch between "Project Guides" (default filtered view) and "All Guides" (full list). Follow these steps:

1. Select a project from the Project dropdown.
2. Set the View dropdown:
   - All Guides — shows all guides in guided development.
   - Project Guides — shows only guides applicable to the selected project.

When All Guides is selected, non-applicable guides are indicated and the UI displays an information icon and message. If a non-applicable guide is opened, display an explicit warning.

LANGUAGE: TEXT

CODE:
```text
Steps:
1. Select project from Project dropdown.
2. In View dropdown, choose:
   - "All Guides" to display all guides.
   - "Project Guides" to display only applicable guides.

Information message shown when "All Guides" selected:
[Information icon] Not all guides are applicable to [project name]. Click here to see all project guides.

Warning message when opening a non-compatible guide:
This guide isn’t compatible with the current project and will not work as intended.
```

STEP: 4 - Visual indicators and exact UI strings

DESCRIPTION: Use these exact UI strings and icon classes when rendering or checking the guided-development UI for compatibility or automation scripts.

LANGUAGE: HTML / TEXT

CODE:
```html
Span for information icon (example):
<span class="SAP-icons-V5"></span>  /* Information icon */

Span for filter icon (example):
<span class="SAP-icons-V5"></span>  /* Filter icon */
```

```text
UI strings:
- Information message (shown with icon when "All Guides" selected):
  "Not all guides are applicable to [project name]. Click here to see all project guides."

- Warning when a guide is not compatible:
  "This guide isn’t compatible with the current project and will not work as intended."
```

STEP: 5 - Filter by tags

DESCRIPTION: Use the Filter icon to select one or more predefined tags. The returned list must include only guides that contain all selected tags (logical AND). Implement multi-tag filtering accordingly.

LANGUAGE: TEXT

CODE:
```text
Filter behavior:
- Click filter icon: <span class="SAP-icons-V5"></span>
- Select one or more tags.
- Result: only guides that include ALL selected tags are displayed (logical AND).
```

STEP: 6 - Search guides text behavior

DESCRIPTION: The Search guides input filters guides by titles, descriptions, annotation terms, and information links. The search is incremental (type-ahead): each new character further narrows results. Use examples when implementing or testing search.

LANGUAGE: TEXT

CODE:
```text
Search behavior:
- Fields searched: title, description, annotation terms, information links.
- Increments on each keystroke (type-ahead).
- Example: To find guides relevant to the UI.LineItem annotation, enter "UI.LineItem" in the Search guides field.
```

STEP: 7 - Example end-to-end usage (interactive flow)

DESCRIPTION: Example sequence to find a specific annotation guide applicable to your project:

1. Select your project in Project dropdown.
2. Ensure View = "Project Guides" to show applicable guides (or "All Guides" to see all).
3. Set Group by = "Application Artifacts" and choose "Annotations" (or specific annotation grouping).
4. Click Filter icon and pick relevant tags.
5. Enter "UI.LineItem" (or any annotation term) in Search guides.
6. Open a guide; if it’s not compatible, detect and surface the warning:
   "This guide isn’t compatible with the current project and will not work as intended."

LANGUAGE: TEXT

CODE:
```text
Example flow:
1. Project = [your-project]
2. View = Project Guides
3. Group by = Application Artifacts -> Annotations
4. Filter by tags = [tag1, tag2]
5. Search = "UI.LineItem"
6. Open guide -> if incompatible, show warning string.
```

fiori-tools guided-development search filters annotations OData SAPUI5 UI5 manifest flex lines


**TITLE**: Sections

**INTRODUCTION**: This document enumerates the section types that can be created, modified, or deleted on Form and Object pages. Use the referenced section files for implementation details and examples. This is a quick index for code-generation and editor automation tasks that need to manipulate page sections.

**TAGS**: fiori-tools, sections, form, object-page, UI5, navigation

**STEP**: 1 — Overview of available sections

**DESCRIPTION**: Review the list of supported section types. Each entry points to a dedicated document containing implementation details. Use these documents when generating, updating, or removing sections in an automated tool or code generator.

**LANGUAGE**: Markdown

**CODE**:
```Markdown
- Form Section: form-section-4102b3d.md
- Table Section: table-section-fc59378.md
- Identification Section: identification-section-b83f501.md
- Group Section: group-section-1894c47.md
- Custom section
```

**STEP**: 2 — Form Section

**DESCRIPTION**: Create, modify, or delete a Form Section on a Form or Object page by following the patterns and examples in the Form Section document. Use this for grouped input fields presented as a form.

**LANGUAGE**: Markdown

**CODE**:
```Markdown
Refer to: form-section-4102b3d.md
```

**STEP**: 3 — Table Section

**DESCRIPTION**: Create, modify, or delete a Table Section on a Form or Object page by following the patterns and examples in the Table Section document. Use this for lists or tabular data embedded in a page.

**LANGUAGE**: Markdown

**CODE**:
```Markdown
Refer to: table-section-fc59378.md
```

**STEP**: 4 — Identification Section

**DESCRIPTION**: Create, modify, or delete an Identification Section on a Form or Object page by following the patterns and examples in the Identification Section document. Use this for key-identifying fields and summary information.

**LANGUAGE**: Markdown

**CODE**:
```Markdown
Refer to: identification-section-b83f501.md
```

**STEP**: 5 — Group Section

**DESCRIPTION**: Create, modify, or delete a Group Section on a Form or Object page by following the patterns and examples in the Group Section document. Use this for logically grouped elements that are not necessarily form fields.

**LANGUAGE**: Markdown

**CODE**:
```Markdown
Refer to: group-section-1894c47.md
```

**STEP**: 6 — Custom section

**DESCRIPTION**: Implement a Custom Section when none of the standard section types fit the requirement. Define the section structure and behavior in your page descriptor or manifest and link to component/template code. Consult the related section documents above for integration patterns and reuse their conventions (naming, placement, lifecycle) when applicable.

**LANGUAGE**: Markdown

**CODE**:
```Markdown
Custom section — implement by creating a new section descriptor and corresponding component/template.
No predefined file: create new documentation or code file alongside:
e.g. custom-section-<identifier>.md
```

Sections

fiori-tools sections form object-page UI5 navigation


**TITLE**: Supported Elements in Page Editor (Configure Page Elements)

**INTRODUCTION**: This reference lists the annotation-based UI elements that the "Configure Page Elements" tool supports for Fiori tools. Use this when generating code or producing annotations to ensure only supported elements are edited via the Page Editor; all other elements must be edited directly in the annotation files.

**TAGS**: fiori-tools, page-editor, configure-page-elements, list-report, object-page, annotations

STEP: 1 — Purpose and scope
DESCRIPTION: Explain when to use the Page Editor vs. direct annotation editing. Use the Page Editor only for the listed, supported elements. For any element not listed here, modify the corresponding annotation file directly.
LANGUAGE: Markdown
CODE:
```markdown
Supported via Configure Page Elements: only the elements listed in this document.
All other UI/annotation elements must be edited directly in the annotation file.
```

STEP: 2 — List Report elements supported by Page Editor
DESCRIPTION: The List Report view supports a large list of items and filtering. Configure the following elements with Configure Page Elements. For full element documentation consult the UI5 topic linked below.
LANGUAGE: JSON
CODE:
```json
{
  "pageType": "ListReport",
  "anchor": "loio47f0424e5bab4efab1cdba3839e18546__section_fst_nyx_dsb",
  "ui5Docs": "https://ui5.sap.com/#/topic/1cf5c7f5b81c4cb3ba98fd14314d4504",
  "supportedElements": [
    {
      "name": "Filter Fields",
      "doc": "filter-fields-0b84286.md"
    },
    {
      "name": "Table",
      "doc": "table-aaff7b1.md"
    }
  ],
  "note": "Only the elements listed above are supported in Configure Page Elements. All other List Report elements must be modified directly in the annotation file."
}
```

STEP: 3 — Object Page and Form Entry elements supported by Page Editor
DESCRIPTION: The Object Page supports display/edit/create of objects, drafts, and complex page layouts. Configure the following elements with Configure Page Elements. Refer to the UI5 Object Page topic for full details.
LANGUAGE: JSON
CODE:
```json
{
  "pageType": "ObjectPage / FormEntry",
  "anchor": "loio47f0424e5bab4efab1cdba3839e18546__section_erd_lby_dsb",
  "ui5Docs": "https://ui5.sap.com/#/topic/645e27ae85d54c8cbc3f6722184a24a1",
  "supportedElements": [
    {
      "name": "Header",
      "doc": "header-a05d7fc.md#loioa05d7fc1bbbf42a0ade9fb50f6b58b56"
    },
    {
      "name": "Form Section",
      "doc": "form-section-4102b3d.md"
    },
    {
      "name": "Table Section",
      "doc": "table-section-fc59378.md"
    },
    {
      "name": "Identification Section",
      "doc": "identification-section-b83f501.md"
    },
    {
      "name": "Group Section",
      "doc": "group-section-1894c47.md"
    },
    {
      "name": "Adding Custom Section",
      "doc": "maintaining-extension-based-elements-02172d2.md#loiode514dafa2364693baeabbb40d564006"
    },
    {
      "name": "Footer",
      "doc": "footer-1b391bd.md"
    }
  ],
  "note": "Only the elements listed above are supported in Configure Page Elements. All other Object Page elements must be modified directly in the annotation file."
}
```

STEP: 4 — Related information and next steps
DESCRIPTION: References for maintaining annotations and additional editing workflows.
LANGUAGE: Markdown
CODE:
```markdown
Related documentation:
- Maintaining Annotations with Language Server: maintaining-annotations-with-language-server-6fc93f8.md
- Configure Page Elements (entry point): configure-page-elements-047507c.md
```

fiori-tools page-editor configure-page-elements list-report object-page annotations


**TITLE**: Configure List Report Table: Sorting and Default Filtering (PresentationVariant & SelectionVariant)

**INTRODUCTION**: This document explains how to configure the List Report table in the Page Editor for SAP Fiori Tools. It focuses on Table presentation (sorting / grouping) via PresentationVariant and default table filtering via SelectionVariant. Use the Page Editor UI to generate, attach, detach, and maintain the relevant annotations. All referenced annotation names, file paths, and UI actions are preserved for automation or code-generation guidance.

**TAGS**: fiori-tools, table, list-report, annotations, UI.LineItem, PresentationVariant, SelectionVariant, sorting, filtering

STEP: 1 — Include SAP icon stylesheet
DESCRIPTION: Add the SAP icons stylesheet reference used by the Page Editor / preview. Place this link where application HTML requires icon styles (e.g., shell or preview page).
LANGUAGE: HTML
CODE:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

STEP: 2 — Table overview and annotation references
DESCRIPTION: The List Report table is based on the UI.LineItem annotation. When generating or editing the List Report, Page Editor exposes annotation-based properties to control table behavior:
- Presentation Variant: attaches UI.SelectionPresentationVariant or UI.PresentationVariant to define sorting/grouping.
- Sort Order: list of properties and directions that the table sorts by.
- Selection Variant: attaches UI.SelectionPresentationVariant or UI.SelectionVariant to define default filters (SelectOptions).
- Default Filter: list of properties and conditions applied by default to the table.

Preserve these annotations in your annotation file and manifest. Page Editor can generate these annotations when you choose the New option.
LANGUAGE: Plaintext
CODE:
```
Annotations referenced:
- UI.LineItem
- UI.SelectionPresentationVariant
- UI.PresentationVariant
- UI.SelectionVariant
- SelectOptions (inside SelectionVariant)
- Capabilities.FilterRestrictions.NonFilterableProperties
- UI.Hidden
- UI.HiddenFilter
```

STEP: 3 — Configure table sorting (Presentation Variant)
DESCRIPTION: Use the Page Editor table node to set sorting via the Presentation Variant property:
1. Open the table node in Page Editor layout tree.
2. Set Presentation Variant to an existing annotation or choose New to generate UI.SelectionPresentationVariant or UI.PresentationVariant.
3. Click Add Sort Property to add one or more direct entity properties to Sort Order.
4. For each sort row, set Property and Direction (ascending/descending).
5. Re-order multiple sort properties by moving rows up/down to set precedence.
6. To detach the Presentation Variant created by Page Editor, set the property to None (this removes the reference; note: deleting the reference does not immediately delete the annotation file entry — use cleanup).
Notes:
- If the List Report uses an Analytical Chart, you can reuse the chart's Presentation Variant; sort order will then apply to both chart and table.
- Setting Presentation Variant to None deletes the UI.SelectionPresentationVariant reference in the manifest.
LANGUAGE: Plaintext
CODE:
```
Presentation Variant options:
- UI.SelectionPresentationVariant
- UI.PresentationVariant
UI actions:
- New (generate annotation)
- Add Sort Property (adds row with Property + Direction)
- Move Up / Move Down (change sort precedence)
- None (detach generated annotation)
```

STEP: 4 — Configure default table filtering (Selection Variant: Annotation)
DESCRIPTION: Use the table node's Selection Variant: Annotation property to attach a SelectionVariant that defines default filters:
1. In Page Editor, set Selection Variant: Annotation to an existing UI.SelectionVariant / UI.SelectionPresentationVariant or choose New to generate it.
2. If the List Report is configured with an Analytical Chart, you cannot maintain the selection variant in Page Editor.
3. To detach, set Selection Variant: Annotation to None.
4. After detaching, run the annotation cleanup procedure to remove unreferenced UI.SelectionPresentationVariant entries from the annotation file.
LANGUAGE: Plaintext
CODE:
```
Selection Variant options:
- UI.SelectionVariant
- UI.SelectionPresentationVariant
UI actions:
- New (generate annotation)
- None (detach selection variant)
Note: When detached, run cleanup to delete unreferenced annotations.
```

STEP: 5 — Define default filters (Selection Variant: Default Filters)
DESCRIPTION: When a Selection Variant annotation is attached, add Default Filters to define default SelectOptions:
1. Click Add Default Filter in the table node.
2. Select an available direct entity property for filtering.
   - Properties annotated with UI.Hidden or UI.HiddenFilter, or listed in Capabilities.FilterRestrictions.NonFilterableProperties are excluded and cannot be selected.
3. Configure filter conditions per row (operators/values as provided by Page Editor UI).
4. Multiple filters can reference the same property (create multiple rows).
5. Remove a default filter by clicking the Delete (trash/wastebasket) icon on the row.
LANGUAGE: Plaintext
CODE:
```
Default Filter actions:
- Add Default Filter (prompts selection among allowed properties)
- Allowed properties exclude:
  - Properties with UI.Hidden
  - Properties with UI.HiddenFilter
  - Properties listed in Capabilities.FilterRestrictions.NonFilterableProperties
- Delete (trash icon) removes the default filter row
```

STEP: 6 — Cleanup unreferenced annotations
DESCRIPTION: After detaching PresentationVariant or SelectionVariant entries (setting to None), run the annotation cleanup procedure to remove unreferenced UI.SelectionPresentationVariant, UI.SelectionVariant, and other qualifier-based unreferenced annotations from the annotation file so the file remains clean.
LANGUAGE: Plaintext
CODE:
```
Cleanup procedure:
- Run "annotation cleanup" that deletes unreferenced annotations created by Page Editor.
- Targets:
  - UI.SelectionPresentationVariant (unreferenced)
  - UI.SelectionVariant (unreferenced)
  - Other unreferenced annotations with qualifier
Note: This is a structural cleanup step; the specific cleanup command/tool depends on your project tooling.
```

STEP: 7 — Reference images and Page Editor UI screenshots
DESCRIPTION: Reference the Page Editor UI screenshots included in the repository for visual guidance when scripting UI automation or building tools that integrate with the Page Editor.
LANGUAGE: Plaintext
CODE:
```
Image assets (relative paths in docs):
- images/Fiori_Tools_Presentation_Variant_Table_d2a0977.png
- images/Default_Filter_Table_4308a97.png
```

fiori-tools table list-report annotations UI.LineItem PresentationVariant SelectionVariant sorting filtering


**TITLE**: Table Actions (fiori-tools)

**INTRODUCTION**: Quick, code-focused reference for configuring table actions and action menus in SAP Fiori tools Page Editor. Covers adding inline (column) and toolbar actions, external navigation (intent-based) actions, action menus, property maintenance, moving and deleting actions. Use these steps to generate or modify annotation records (UI.DataFieldForAction / UI.DataFieldForIntentBasedNavigation) and to verify required launchpad/manifest configuration.

**TAGS**: fiori-tools, table-actions, UI.DataFieldForAction, UI.DataFieldForIntentBasedNavigation, annotations, semantic-object, manifest.json, cross-application-navigation

STEP: Required assets (CSS)
DESCRIPTION: Ensure UI icons/CSS are available in the editor preview or documentation pages. This is the exact stylesheet link referenced by the original docs.
LANGUAGE: HTML
CODE:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

STEP: Preconditions and scope for adding actions
DESCRIPTION: Verify available service metadata and bound actions/functions before adding table actions. Only actions/functions bound to the same entity type as the UI.LineItem of the target table are available. For external navigation actions, you must know the target application semantic object and action (as configured in the Fiori launchpad).
LANGUAGE: Text
CODE:
```text
Preconditions:
- Bound actions/functions must be defined on the same entity type used by UI.LineItem for the table.
- For external navigation: know the Semantic Object Name and Semantic Object Action of the target app (configured in Fiori launchpad).
- Configure cross-application navigation in both the launchpad and the target app's manifest.json.
```

STEP: Add a table action (inline column or toolbar)
DESCRIPTION: Use the Page Editor node for the table (List Report: Columns or Tool Bar; Object Page: Table section Columns or Tool Bar). Click Add (+) and choose Action or Function for in-app actions, or choose External Navigation and supply Semantic Object/Action for intent-based navigation. The editor will create a UI.DataFieldForAction or UI.DataFieldForIntentBasedNavigation record and set Inline = true when added as a table column.
LANGUAGE: Text
CODE:
```text
Page Editor -> Select Table node -> Columns or Tool Bar -> Click + (Add)
Choose:
- "Action" or "Function" for in-app action (creates UI.DataFieldForAction)
- "External Navigation" for intent-based navigation (creates UI.DataFieldForIntentBasedNavigation)
Result: UI.DataFieldForAction or UI.DataFieldForIntentBasedNavigation added.
If added as a table column: Inline is set to true.
```

STEP: UI.DataFieldForAction property example (Inline)
DESCRIPTION: Inline property controls whether an action appears as an inline column (true) or in the toolbar (false). When moved between toolbar and columns the Inline value toggles accordingly. Use this property when generating or modifying annotation JSON/EDMX.
LANGUAGE: JSON
CODE:
```json
{
  "RecordType": "UI.DataFieldForAction",
  "Action": "YourBoundActionName",
  "Inline": true,
  "Label": "My Action"
}
```

STEP: Add an external navigation action (intent-based)
DESCRIPTION: Supply Semantic Object Name and Semantic Object Action exactly as configured in the target application. The generated label is "Action SemanticObject" (e.g., Semantic Object = Customer, Action = display -> "Display Customer"). Configure mapping if local property names differ from the target app. If added to toolbar, optionally set RequiresContext to require a selected row.
LANGUAGE: JSON
CODE:
```json
{
  "RecordType": "UI.DataFieldForIntentBasedNavigation",
  "SemanticObject": "Customer",
  "Action": "display",
  "Inline": true,
  "Label": "Display Customer",
  "RequiresContext": false
}
```

STEP: Add an action menu to a toolbar
DESCRIPTION: In the Table node Tool Bar, click the Add Actions icon, choose Add Action Menu, provide a Label, and select actions to include. Rules: an action cannot be in two action menus, and an action cannot be both inside and outside an action menu simultaneously. You cannot remove the last action from an action menu if that would leave zero actions.
LANGUAGE: Text
CODE:
```text
Page Editor -> Table node -> Tool Bar -> Add Actions icon -> Add Action Menu
- Enter Label for menu
- Select actions to include (each action can be in at most one menu)
- Click Add
```

STEP: Label handling for actions and menus
DESCRIPTION: Label sourcing and overrides:
- For in-app actions: Label uses Common.Label or @title (CAP CDS) when present; otherwise Label is generated in UI.DataFieldForAction and can be edited. Deleting a table action removes only the UI.DataFieldForAction record; Common.Label or @title annotations remain.
- For intent-based actions: Label is generated from Semantic Object and Semantic Object Action entered when creating the action.
- For action menus: Label is user-provided at creation.
LANGUAGE: Text
CODE:
```text
Label priority for in-app action:
1. Common.Label / @title annotation (if present)
2. UI.DataFieldForAction.Label (generated or edited)

Note: Deleting UI.DataFieldForAction removes the Label property stored on that record; annotation-based labels remain in annotation source.
```

STEP: Importance and Hidden properties
DESCRIPTION: Importance is set when an action is added as a table column (see table columns/importance). Use Hidden or annotation-based HideByProperty rules to hide actions or menus in UI. These are persisted on the annotation record.
LANGUAGE: Text
CODE:
```text
UI.DataFieldForAction properties to consider:
- Importance: defined for column actions (affects column visibility)
- Hidden: set to hide action (can also be controlled by annotation HideByProperty)
```

STEP: Criticality for inline actions
DESCRIPTION: For inline table actions (columns), set Criticality to Positive/Negative to apply semantic highlight colors. Toolbar buttons do not support semantic highlighting; criticality is not available for toolbar actions. To remove highlighting set Criticality = None.
LANGUAGE: JSON
CODE:
```json
{
  "RecordType": "UI.DataFieldForAction",
  "Action": "ApproveOrder",
  "Inline": true,
  "Criticality": "Positive"   // Possible values: Positive, Negative, None
}
```

STEP: Semantic mapping for external navigation
DESCRIPTION: If the semantic object property name differs between the current app and the target application, add a semantic mapping: map the target semantic object property name to a local property. Only one mapping per external navigation action is supported.
LANGUAGE: JSON
CODE:
```json
{
  "RecordType": "UI.DataFieldForIntentBasedNavigation",
  "SemanticObject": "TargetSemanticObject",
  "Action": "display",
  "SemanticObjectMappings": [
    {
      "TargetProperty": "CustomerID",
      "LocalProperty": "CustID"
    }
  ]
}
```

STEP: RequiresContext behavior for toolbar intent-based actions
DESCRIPTION: When adding an external navigation action to a toolbar, set RequiresContext = true to require a selected table row as navigation context. Default is false (context not required). This property is not available for inline/column actions because context is always the row.
LANGUAGE: JSON
CODE:
```json
{
  "RecordType": "UI.DataFieldForIntentBasedNavigation",
  "SemanticObject": "Customer",
  "Action": "display",
  "RequiresContext": true
}
```

STEP: Moving actions and action menus
DESCRIPTION: Move actions only within the same table. Moving between toolbar and columns toggles Inline accordingly. Action menus and contained actions can be moved, but you cannot move the last action out of a menu if it would empty the menu.
LANGUAGE: Text
CODE:
```text
Move rules:
- Same-table moves only
- Moving to Columns -> set Inline = true
- Moving to Toolbar -> set Inline = false
- Cannot leave an action menu empty by moving its last action out
```

STEP: Deleting actions and action menus
DESCRIPTION: Remove actions or action menus in the Page Editor by clicking the Delete (wastebasket) icon. Deleting a UI.DataFieldForAction or UI.DataFieldForIntentBasedNavigation removes that specific annotation record; shared annotation labels (Common.Label/@title) are not removed.
LANGUAGE: Text
CODE:
```text
Page Editor -> Select action or action menu -> Click Delete (wastebasket)
Note: Deleting removes the UI.DataFieldForAction or UI.DataFieldForIntentBasedNavigation record only.
```

STEP: Cross-application navigation configuration reminder
DESCRIPTION: To enable intent-based navigation at runtime, configure the Fiori launchpad and the target application's manifest.json correctly. Verify Semantic Object and Action names match the launchpad intent configuration.
LANGUAGE: Text
CODE:
```text
Required:
- Configure target app intent in SAP Fiori launchpad (semantic object & action)
- Ensure target app manifest.json and role/target mappings are correctly set in the launchpad configuration
- Use matching SemanticObject and Action values in UI.DataFieldForIntentBasedNavigation
```

Table Actions (fiori-tools)


**TITLE**: Table Columns — Add, Configure, and Annotation Behavior

**INTRODUCTION**: How to add and configure table columns in a Fiori Object Page using the Page Editor. Explains supported column types, how labels are resolved and maintained (Common.Label / @title), how importance is applied and inherited from base layers, and how to configure column hiding via a boolean property.

**TAGS**: fiori-tools, table, object-page, annotations, UI.DataField, Common.Label, @title, UI.Importance, documentation

**STEP**: 1 — Add a Column in the Page Editor

**DESCRIPTION**: Use the Page Editor to add a column to a Table or Table Section. Select the column type, supply required values, then click Add. After adding, you can reorder, delete, or edit column-specific properties in the Property Panel.

**LANGUAGE**: UI (Page Editor instructions)

**CODE**:
```text
UI workflow:
- Expand the Table or Table Section node in the Page Editor.
- Click the + (Add) icon next to Columns.
- Select the desired column type.
- Enter the requested information and click Add.
- Use the Property Panel to edit: Label, Importance, Hidden, and type-specific properties.
- Reorder or delete columns directly in the Table node.
```

**STEP**: 2 — Supported Column Types (use these when adding)

**DESCRIPTION**: All supported column types you can add via the Page Editor. Use the specific Property Panel for each type to configure properties.

**LANGUAGE**: text/links

**CODE**:
```text
Supported column types:
- Basic Columns (basic-columns-5f8c75b.md)
- Rating Column (rating-column-b2ba7b4.md)
- Progress Column (progress-column-0039256.md)
- Chart Column (chart-column-b78b302.md)
- Table Actions (table-actions-da1931b.md)
- Contact Column (contact-column-dc5931d.md)
- External Navigation Column (table-actions-da1931b.md)
```

**STEP**: 3 — Label resolution and maintenance (Common.Label and @title)

**DESCRIPTION**: When a column is added, the Page Editor checks the property used as the column value for Common.Label (annotation) and @title (CAP/CDS). If either exists, the generated UI.DataField record will not include a Label property — the column title is taken from Common.Label or @title and displayed in the Property Panel. If no such annotation exists, a UI.DataField record is generated with an auto-generated label you can override in the Property Panel.

Editing the column Label in the Property Panel:
- Does NOT change Common.Label or @title in source annotations.
- Instead, the editor adds a Label property to the local UI.DataField record so the change is limited to this table column.

Deleting a column:
- Does NOT remove Common.Label or @title annotations.
- Removes only local Label properties that were added directly to the UI.DataField record (since the record is removed).

Include the following file reference in pages that use icon CSS:
- ../css/sap-icons.css

**LANGUAGE**: XML, CDS

**CODE**:
```xml
<!-- Example: generated UI.DataField without local Label if Common.Label exists -->
<Record Type="UI.DataField">
  <!-- No PropertyValue for Label if Common.Label/@title is present -->
  <PropertyValue Property="Value" Path="ProductName"/>
</Record>

<!-- Example: generated UI.DataField with local Label when no annotation exists -->
<Record Type="UI.DataField">
  <PropertyValue Property="Label" String="Product"/>
  <PropertyValue Property="Value" Path="ProductName"/>
</Record>
```

```cds
// Example CAP/CDS: @title used by Page Editor to set column label
entity Product {
  @title: 'Product'
  ProductName : String;
}
```

**STEP**: 4 — Importance behavior and layer inheritance

**DESCRIPTION**: When a column is created, Importance defaults to None (no importance specified). Use Importance to indicate which columns should be shown on small screens. If a UI.LineItem in a lower (base) layer defines importance for the same column, the Page Editor displays the base-layer value in the dropdown with the suffix "(base layer)" (e.g., "High (base layer)"). If you explicitly change Importance to None in your layer, the local UI.Importance annotation is removed from your local annotation file.

**LANGUAGE**: XML (annotation example)

**CODE**:
```xml
<!-- Example: UI.Importance set on a DataField within UI.LineItem -->
<Record Type="UI.DataField">
  <PropertyValue Property="Value" Path="ProductName"/>
  <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
</Record>

<!-- If base layer annotation exists, UI shows: "High (base layer)" in dropdown -->
```

**STEP**: 5 — Hidden property and "Hide by Property" condition

**DESCRIPTION**: Toggle the Hidden property in the Property Panel to mark the column as hidden in the application UI. When Hidden is activated, pick a boolean property from the entity as the hiding condition in the "Hide by Property" field. The editor uses that boolean property as the runtime condition to hide/show the column in the app.

- Choose an existing boolean property, e.g., IsArchived or IsHidden.
- The Page Editor stores the hide condition in the local annotation/config so it applies only to the column in this context.

**LANGUAGE**: UI (Page Editor instructions)

**CODE**:
```text
Hidden setup in Page Editor:
- Open the column's Property Panel.
- Toggle "Hidden" ON.
- In "Hide by Property" choose a boolean property from the entity (e.g., IsHidden).
- Save. The column will be hidden at runtime when the boolean is true.
```

**STEP**: 6 — Editing and cleanup rules

**DESCRIPTION**: Summary of what is changed in annotations when editing columns:
- Changing Label in Property Panel creates a local Label on UI.DataField; Common.Label/@title remain unchanged.
- Setting Importance to None removes UI.Importance from the local annotation file.
- Deleting a column removes its local UI.DataField record but does not remove Common.Label or @title annotations defined in shared/base layers.

**LANGUAGE**: text

**CODE**:
```text
Annotation change rules:
- Edit Label -> add local Label to UI.DataField (no change to Common.Label/@title).
- Importance = None -> remove local UI.Importance annotation.
- Delete column -> remove local UI.DataField record only; Common.Label/@title preserved.
```


**TITLE**: Table Section — Add, Move, Delete, and Maintain Table Sections (Fiori Tools)

**INTRODUCTION**: This document describes the exact steps and side effects when working with Table Sections in the Fiori Tools Page Editor (Object/Form Entry Page). It is focused on actions that modify UI annotations (UI.Facets, UI.LineItem) and the CAP CDS cleanup behavior. Use this for automating UI annotation changes or implementing editor integrations.

**TAGS**: fiori-tools, object-page, table-section, UI.Facets, UI.LineItem, annotations, CAP, CDS, cleanup, editor

STEP: Add Table Section

DESCRIPTION:
- Use the Page Editor to add a Table Section to a page. The editor flow:
  1. Open the Object/Form Entry Page (Page Editor).
  2. In the outline, select the section node and click Add (plus icon).
  3. Choose "Add Table Section" from the dropdown.
  4. In the Add Table Section popup, enter Label and Value Source Entity and click Add.
- Side effects in annotation files and CAP CDS:
  - A new `UI.LineItem` (empty collection) is created.
  - A new reference facet is added to `UI.Facets` with an `annotationPath` pointing to the created `UI.LineItem`.
  - If `UI.Facets` does not exist for the entity, a `UI.Facets` annotation is created under the entity associated with the Object Page.
  - If `UI.Facets` exists on an underlying layer, the annotation in the underlying layer is overridden.
  - For CAP CDS projects, a using statement is added to the overridden file if it is missing.

LANGUAGE: HTML

CODE:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

LANGUAGE: text

CODE:
```
Annotation changes performed:
- Create UI.LineItem (empty)
- Create referenceFacet in UI.Facets with annotationPath -> new UI.LineItem
- If missing, create UI.Facets under the entity for the Object Page
- Override underlying-layer UI.Facets if present
- CAP CDS: add using statement to overridden file if missing
```

STEP: Move Table Section

DESCRIPTION:
- Reorder sections using drag-and-drop in the Page Editor outline.
- Behavior:
  - Drag the required section to the new position and drop.
  - The records in the `UI.Facets` collection are reordered.
  - The runtime rendering of sections follows the record sequence in `UI.Facets`.
- Move multiple sections:
  1. Select multiple sections using Ctrl + Click.
  2. Drag the selected group to the new position.

LANGUAGE: text

CODE:
```
Behavior when reordering:
- Update sequence of records in UI.Facets to match new outline order
- Display order in rendered Fiori application follows UI.Facets sequence
Mass-move steps:
- Ctrl + Click to multi-select sections
- Drag selected sections and drop at target position
```

STEP: Delete Table Section

DESCRIPTION:
- Delete a section from the Page Editor:
  1. Navigate to the section layer in the outline.
  2. Click the Delete (wastebasket) icon to open Delete Confirmation.
  3. Click Delete to confirm.
- Effects:
  - The referenced facet record is removed from `UI.Facets` for the section in the Appendix.
  - Orphaned `UI.LineItem` annotations are not automatically removed — you must run the cleanup procedure separately to delete unreferenced annotations.

LANGUAGE: text

CODE:
```
Delete actions:
- Remove referenced facet record from UI.Facets
- Note: Orphaned UI.LineItem annotation persists until cleanup procedure is executed
```

STEP: Maintain Table Section Properties — Label

DESCRIPTION:
- Change the section label shown in the editor and preview:
  1. Select the section in the Page Editor.
  2. In the properties pane, edit the Label text box with the new display text.
- Effect:
  - The section label updates in the Page Editor and in the application preview.
- See Appendix for more details:
  - Label reference: appendix-457f2e9.md#loiod44832d99bdf4f73ba14cdbb16dc9301

LANGUAGE: text

CODE:
```
Property to edit: Label
- Update Label in properties pane -> reflected in Page Editor + preview
Reference: appendix-457f2e9.md#loiod44832d99bdf4f73ba14cdbb16dc9301
```

STEP: Maintain Table Section Properties — Hidden

DESCRIPTION:
- Hidden property is managed via the properties pane. See the Hidden appendix for full behavior and expression details.

LANGUAGE: text

CODE:
```
Hidden property:
- Refer to: appendix-457f2e9.md#loiof7ad71792a0044d6b6172f078827bdc0
```

STEP: Related Resources

DESCRIPTION:
- Quick links for related Table configuration pages.

LANGUAGE: text

CODE:
```
Related:
- Table Actions: table-actions-da1931b.md
- Table Columns: table-columns-a80d603.md
- Add/Move/Label/Delete Table Section anchors:
  - Add: table-section-fc59378.md#loiofc593789991c46348b31c1bc3b9d9182__section_g5r_hpb_zrb
  - Move: table-section-fc59378.md#loiofc593789991c46348b31c1bc3b9d9182__section_udp_pxx_xrb
  - Label: table-section-fc59378.md#loiofc593789991c46348b31c1bc3b9d9182__section_yn2_2qb_zrb
  - Delete: table-section-fc59378.md#loiofc593789991c46348b31c1bc3b9d9182__section_cwh_qxx_xrb
```

fiori-tools object-page table-section UI.Facets UI.LineItem annotations CAP CDS cleanup editor


**TITLE**: Taskbar Notification for Annotation File Updates in Page Editor

**INTRODUCTION**: Describe and implement the UX behavior where a taskbar notification appears when an annotation file is updated as a result of the user's actions in the Page Editor. The notification must not appear when the annotation file is modified directly (manual file edit). Use the patterns below to detect origin, build the notification payload, and display actionable notifications.

**TAGS**: fiori-tools, taskbar, notification, annotation, page-editor, ux, editor-events

**STEP**: 1 - Event payload contract (example)

**DESCRIPTION**: Define a minimal event payload contract that the Page Editor should emit when an annotation file is updated as a result of a user action. Include a field that identifies the origin so the notification logic can decide whether to show a taskbar notification.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "event": "annotationFileUpdated",
  "payload": {
    "filePath": "manifest/annotations/Annotations.xml",
    "timestamp": "2026-01-28T12:34:56Z",
    "origin": "page-editor",          // possible values: "page-editor", "direct-file-edit", "sync", "cli"
    "userId": "user@example.com",
    "summary": "Added metadata for control XYZ",
    "diffSummary": {
      "added": 3,
      "modified": 1,
      "removed": 0
    }
  }
}
```

**STEP**: 2 - Listener and origin check

**DESCRIPTION**: Register a listener for the annotation update event. Only show a taskbar notification if the event origin equals "page-editor" (or other allowed editor-origin values). Ignore events where origin indicates a direct file edit.

**LANGUAGE**: TypeScript

**CODE**:
```typescript
// Pseudocode TypeScript example: integrate into Page Editor extension/plugin
type AnnotationEvent = {
  event: string;
  payload: {
    filePath: string;
    timestamp: string;
    origin: string; // "page-editor" | "direct-file-edit" | ...
    summary?: string;
    diffSummary?: { added?: number; modified?: number; removed?: number };
  };
};

function registerAnnotationListener(eventBus: { on: (evt: string, cb: (e: AnnotationEvent) => void) => void }) {
  eventBus.on('annotationFileUpdated', (e: AnnotationEvent) => {
    const origin = e.payload.origin ?? 'unknown';
    if (origin === 'page-editor') {
      showTaskbarNotificationForAnnotation(e.payload);
    } else {
      // Do not show taskbar notification for direct file edits or non-editor origins
      console.debug(`annotationFileUpdated ignored for origin=${origin}`);
    }
  });
}
```

**STEP**: 3 - Build and display taskbar notification with actions

**DESCRIPTION**: Construct a concise notification message and provide helpful actions (e.g., "Open Annotation", "View Changes", "Dismiss"). The notification should include the file path and a short summary. Use the host platform / framework notification API; example below shows a generic notification builder with callbacks for actions.

**LANGUAGE**: TypeScript

**CODE**:
```typescript
// Generic taskbar notification builder (pseudocode)
type NotificationAction = { id: string; label: string; callback: () => void };
type TaskbarNotification = {
  title: string;
  message: string;
  actions?: NotificationAction[];
  timestamp?: string;
};

function showTaskbarNotificationForAnnotation(payload: AnnotationEvent['payload']) {
  const filePath = payload.filePath;
  const summary = payload.summary ?? 'Annotation file updated';
  const title = 'Annotation updated';
  const message = `${summary} — ${filePath}`;

  const notification: TaskbarNotification = {
    title,
    message,
    timestamp: payload.timestamp,
    actions: [
      { id: 'open', label: 'Open Annotation', callback: () => openFileInEditor(filePath) },
      { id: 'view', label: 'View Changes', callback: () => openDiffViewer(filePath) },
      { id: 'dismiss', label: 'Dismiss', callback: () => {/* no-op */} }
    ]
  };

  // Replace with host platform API, e.g., VS Code: window.showInformationMessage(...)
  displayTaskbarNotification(notification);
}

function openFileInEditor(path: string) {
  // host-specific implementation
  console.log(`Open file: ${path}`);
}

function openDiffViewer(path: string) {
  // host-specific implementation to show changes/diff for path
  console.log(`Open diff for: ${path}`);
}

function displayTaskbarNotification(n: TaskbarNotification) {
  // Example: map to platform-specific notification API
  console.info(`[NOTIFICATION] ${n.title}: ${n.message}`);
  // Show actions to user and hook callbacks
}
```

**STEP**: 4 - Do not show notification for direct annotation file edits

**DESCRIPTION**: Ensure file-system watchers or external file-change events that originate from manual file edits do not trigger the taskbar notification. Use the origin field from the event, or, if the origin is not provided, determine whether the change was caused by in-editor actions vs external edits (e.g., by comparing editor edit context, last known editor state, or a per-change flag).

**LANGUAGE**: TypeScript

**CODE**:
```typescript
// Example guard when origin is not explicit: compare last editor activity
async function handleFileChangeEvent(filePath: string, changeInfo: { modifiedBy?: string }) {
  const lastEditorAction = await getLastEditorActionForFile(filePath); // host-specific
  const isFromEditor = lastEditorAction && (Date.now() - lastEditorAction.timestamp) < 5000; // 5s heuristic

  if (isFromEditor) {
    // treat as page-editor origin
    showTaskbarNotificationForAnnotation({
      filePath,
      timestamp: new Date().toISOString(),
      origin: 'page-editor',
      summary: `Updated via editor by ${lastEditorAction.user}`
    });
  } else {
    // Likely direct file edit; do not show taskbar notification
    console.debug('File changed externally; taskbar notification suppressed', filePath);
  }
}
```

**STEP**: 5 - Notification content recommendations

**DESCRIPTION**: Use these concise content and action recommendations for consistent UX:
- Title: "Annotation updated"
- Message: one-line summary + file path
- Actions: "Open Annotation", "View Changes", "Dismiss"
- Avoid showing notifications for direct file edits
- If multiple annotation files update at once, aggregate into a single notification that lists changed files

**LANGUAGE**: JSON

**CODE**:
```json
{
  "notificationTemplate": {
    "title": "Annotation updated",
    "message": "<summary> — <filePath>",
    "actions": ["Open Annotation", "View Changes", "Dismiss"],
    "aggregateTitle": "Multiple annotation files updated",
    "aggregateMessage": "N annotation files were modified by your recent editor actions"
  }
}
```

fiori-tools taskbar notification annotation page-editor ux editor-events


**TITLE**: Guided Development — Launch, Project Management, and Accessibility

**INTRODUCTION**: This guide explains how to open and use Guided Development for SAP Fiori elements projects inside the SAP Fiori tools environment. It covers launching methods (Command Palette and folder context menu), selecting/changing projects, when to refresh the view, required project data available to the guides, and keyboard accessibility instructions. Use the code snippets and paths provided to integrate assets or automate steps.

**TAGS**: fiori-tools, guided-development, sap-fiori, vscode, accessibility, project-management

**STEP**: 1 — Include SAP icon stylesheet in documentation or extension UI

**DESCRIPTION**: If your Guided Development UI or documentation requires SAP icon fonts, ensure the stylesheet is referenced. Preserve the relative path exactly as used in this doc structure.

**LANGUAGE**: HTML

**CODE**:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

**STEP**: 2 — Open Guided Development using the Command Palette

**DESCRIPTION**: Use the editor Command Palette to open Guided Development in the current editor or to the side. These exact command names must be available in the palette integration for automation or extension wiring.

- Keyboard shortcut to open Command Palette:
- Commands to display in the palette:
  - Fiori: Open Guided Development
  - Fiori: Open Guided Development to the Side
- Selecting a project from the workspace is required after opening.

**LANGUAGE**: Plain Text

**CODE**:
```
Shortcut: [CMD/CTRL] + [Shift] + [P]
Start typing: "guided development"
Commands:
  - Fiori: Open Guided Development
  - Fiori: Open Guided Development to the Side
Behavior:
  - "Open Guided Development" opens in current region/tab.
  - "Open Guided Development to the Side" opens in a new column beside the current file.
```

**STEP**: 3 — Open Guided Development using the folder context menu

**DESCRIPTION**: If a workspace folder contains an SAP Fiori elements project, the context menu should allow opening Guided Development directly for that project.

**LANGUAGE**: Plain Text

**CODE**:
```
Right-click project folder -> SAP Fiori tools - Open Guided Development
Behavior:
  - Opens Guided Development to the side of the current file in another column.
Note:
  - If no Fiori elements project exists in workspace, Command Palette still allows opening the UI, but interactive features are disabled (you can view guides and code samples only).
```

**STEP**: 4 — Select or change the active project in Guided Development

**DESCRIPTION**: Guided Development operates on one project at a time. Use the Select Project action in the toolbar to choose which workspace project provides project-specific data to the guides. The active project name appears in the tab header.

**LANGUAGE**: Plain Text

**CODE**:
```
Actions:
  1. Click "Select Project" on left side of the toolbar.
  2. Pick a project from the Project list.

UI assets:
  - Example screenshot path: images/SelectProject_9ea63e4.png

Active project provides:
  - Entity list (Entities available in the service)
  - Model list (Data sources)
  - Page list (Application pages)
  - Annotation terms defined in the service across guides

Note:
  - Annotations from services other than the 'mainService' can be added in Guided Development.
```

**STEP**: 5 — When and how to refresh Guided Development project data

**DESCRIPTION**: Refresh Guided Development when workspace project state changes or new projects are added. Provide a refresh icon in the Project list and toolbar to re-scan workspace/project resources.

**LANGUAGE**: Plain Text

**CODE**:
```
When to refresh:
  - When a new project is added to the workspace.
  - When something in the current project is changed outside Guided Development (e.g., a new page is added or service updates).

How to refresh:
  - Click the Refresh icon inside the Project list.
  - Click the Refresh icon on the toolbar next to the Project list.

Icon HTML snippet used in docs (representative):
  <span class="SAP-icons-V5"></span>  (Refresh)
```

**STEP**: 6 — Keyboard navigation and accessibility support

**DESCRIPTION**: Ensure Guided Development UI supports keyboard navigation and high contrast themes. Document the specific navigation keys for implementers and automated tests.

**LANGUAGE**: Plain Text

**CODE**:
```
Keyboard navigation:
  - Arrow keys: navigate within sections and lists
  - Tab: move focus forward to next section or control
  - Shift + Tab: move focus backward
  - Enter: activate the focused item or make selection

Accessibility support:
  - High contrast themes are supported; ensure all controls expose focus and state to assistive technologies.
```

fiori-tools guided-development sap-fiori vscode accessibility project-management


**TITLE**: Visualizing and Managing Annotations with SAP Fiori Tools - Service Modeler

**INTRODUCTION**: Action-oriented guide for developers to view, search, override, edit, and delete OData and CAP service annotations using SAP Fiori tools - Service Modeler and the XML Code Editor. Includes file locations, UI actions, and exact command names for automation/scripts or extension integration.

**TAGS**: fiori-tools, service-modeler, annotations, OData, CAP, xml, annotation-file, vscode

STEP: Supported Annotation Types and Identification

DESCRIPTION: Service Modeler supports OData service and CAP service annotations. Annotations are associated with entity types, entities, and properties. In the tree list they are identified by the Annotations icon; use this icon to locate annotated targets programmatically or when scripting UI actions.

LANGUAGE: HTML

CODE:
```html
<!-- Annotation icon markup used in UI tree -->
<span class="SAP-icons-V5"></span> <!-- "Annotations" icon -->
```

STEP: Include Service Modeler Icons/CSS (for UI previews or extension testing)

DESCRIPTION: If you render Service Modeler UI previews or develop extensions that reference SAP icons, include the SAP icons stylesheet used by the docs/UI to ensure icons render correctly.

LANGUAGE: HTML

CODE:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

STEP: Annotation File Location and Precedence

DESCRIPTION: Local annotation files override backend annotations when they define the same annotation term + qualifier on the same target. Local annotation files live in the project under /webapp/annotations. Use this path to locate files for automated editing, validation, or packaging.

LANGUAGE: text

CODE:
```
Local annotations folder (project):
/webapp/annotations/<filename>.xml
Notes:
- Local annotations override backend annotations with same term+qualifier on same target.
- Backend annotations are read-only in Service Modeler but can be overridden locally.
- To edit local files, open them in the XML Code Editor (see link below).
```

STEP: Open Service Modeler — Command Palette

DESCRIPTION: Launch Service Modeler via VS Code Command Palette. Use exact command text to automate invocation or to guide users/programmatic flows.

LANGUAGE: text

CODE:
```
Command Palette sequence:
1. Open Command Palette (Ctrl/Cmd+Shift+P)
2. Type: Fiori: Service Modeler: Open Service Modeler
3. Select your SAP Fiori elements project in the workspace
```

STEP: Open Service Modeler — Folder Context Menu

DESCRIPTION: When a Fiori elements project is in the workspace, right-click a folder to use the Override Annotations context action. Use this method in UI-driven workflows or extension context menu contributions.

LANGUAGE: text

CODE:
```
Context menu:
Right-click any folder in the target Fiori elements project -> Override Annotations
(Select project folder if multiple projects exist)
```

STEP: Open Service Modeler — From Metadata Editor

DESCRIPTION: When a metadata.xml file is open in the editor, click the Annotations icon to open Service Modeler focused on that service metadata. This is useful for linking editor state to Service Modeler.

LANGUAGE: HTML

CODE:
```html
<!-- Example: clicking the Annotations icon in the metadata editor -->
<span class="SAP-icons-V5"></span> <!-- Click to open Service Modeler for the metadata.xml -->
```

STEP: View Annotations for an Entity/Property

DESCRIPTION: Select the target entity type or property in the Service Modeler tree to highlight its annotations in the Annotation panel. Use the Show in Source action to open the source annotation file and highlight the annotation occurrence.

LANGUAGE: text

CODE:
```
View sequence:
1. In tree list, select an entity type or a property (expanding entity types if needed).
2. The Annotation panel highlights annotations for the selected target.
3. Click the "Show in Source" icon beside an annotation to open the source file with the annotation highlighted.
```

STEP: Show in Source Icon (UI element)

DESCRIPTION: The Show in Source icon opens the file where the selected annotation is defined (backend or local). Use this identifier when scripting or documenting UI steps.

LANGUAGE: HTML

CODE:
```html
<!-- Show in Source icon image reference -->
<img src="images/show_source_icon_dd4bbff.png" alt="Show in Source" />
```

STEP: Search Annotations

DESCRIPTION: Use the search input (upper-right of Service Modeler) to filter annotations. Matching annotations are listed in the Annotation panel and the tree list is filtered to show only associated entity types/properties. Useful for automated scanning or test scripts that validate annotation presence.

LANGUAGE: text

CODE:
```
Search behavior:
- Enter search criteria in the Annotation panel search box (top-right).
- Results: Annotation panel shows matching annotations; tree list filters to associated targets.
```

STEP: Edit Local Annotations (via XML Code Editor)

DESCRIPTION: Backend annotations are read-only. To change behavior, override annotations in a local annotation file under /webapp/annotations and edit that file with the XML Code Editor. Service Modeler lets you jump to the local source; then edit and save.

LANGUAGE: text

CODE:
```
Edit local annotations workflow:
1. Select target entity set in tree list to highlight annotations.
2. Click "Show in Source" next to a local annotation entry (opens /webapp/annotations/<filename>.xml).
3. Edit the annotation in the XML Code Editor (or any text editor).
4. Save file to apply overrides; local annotations take precedence over backend.
Reference: XML Code Editor docs:
maintaining-annotations-with-language-server-6fc93f8.md#loio6fc93f80827940809437365abdf85b75__XML_Code_Editor
```

STEP: Screenshot / Visual Reference for Editing

DESCRIPTION: Visual confirmation of editing flow—Service Modeler opens the local annotation file and the XML Code Editor shows the selected annotation highlighted.

LANGUAGE: HTML

CODE:
```html
<!-- Example image showing editing flow -->
<img src="images/Editing_annotations_c97d919.png" alt="Editing annotations in XML Code Editor" />
```

STEP: Delete Local Annotation

DESCRIPTION: Delete an annotation defined in a local annotation file using the Delete (wastebasket) icon in the Annotation panel. This removes the local override; backend annotation (if present) will become visible again unless the backend annotation is absent.

LANGUAGE: text

CODE:
```
Delete workflow:
1. Select the target entity type or property in the tree list.
2. In the Annotation panel, click the Delete (wastebasket) icon adjacent to the local annotation in /webapp/annotations/<filename>.xml.
3. Confirm deletion if prompted and save the local annotation file.
```

STEP: Notes and Constraints for Automation and Tooling

DESCRIPTION: Key constraints to account for in code generation, automation, or tests:
- Only OData and CAP annotations supported.
- Backend annotations are read-only in Service Modeler; always create/modify local overrides under /webapp/annotations.
- Local annotations override backend annotations that match by term and qualifier on the same target.
- Use exact command name "Fiori: Service Modeler: Open Service Modeler" for automation or extension activation.

LANGUAGE: text

CODE:
```
Constraints summary:
- Supported: OData service annotations, CAP service annotations.
- Local file path: /webapp/annotations/<filename>.xml
- Local overrides win over same-term backend annotations with same qualifier on same target.
- Backend annotations cannot be edited directly in Service Modeler.
```

fiori-tools service-modeler annotations OData CAP xml annotation-file vscode


**TITLE**: Working with Local and Back End Annotations in SAP Fiori Tools

**INTRODUCTION**: Practical guide for developers to locate, register, override, and maintain OData annotation files generated or added in a SAP Fiori Tools project. Includes file locations, manifest registration patterns, and the recommended workflow for overriding back end annotations in local files.

**TAGS**: fiori-tools, annotations, OData, manifest.json, webapp/annotations, webapp/localService, override, Service Modeler

**STEP**: 1 — Locate local annotation files and copied back end artifacts

**DESCRIPTION**: Identify where annotation files and back end copies are stored after project generation. Use these paths when editing or registering annotations.

**LANGUAGE**: Text

**CODE**:
```text
- Local annotation files generated by Fiori Tools:
  webapp/annotations/

- Back end service metadata and back end annotation files are copied to:
  webapp/localService/

- The project manifest (manifest.json) contains references to these local copies.
  Use "localUri" to reference the local copy; use "uri" to reference the original back end path.
```

**STEP**: 2 — Example manifest.json registration (localUri vs uri)

**DESCRIPTION**: Register your OData service and annotation data sources in manifest.json so the app uses local copies during development. The example below shows:
- data source for the OData service with a local copy of metadata (localUri)
- annotation data source with both a back end uri and a local override (localUri)

Adjust paths and keys to match your project naming.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.app": {
    "id": "my.app.id",
    "dataSources": {
      "mainService": {
        "uri": "/sap/opu/odata/sap/API_EXAMPLE_SRV/",
        "type": "OData",
        "settings": {
          "localUri": "webapp/localService/metadata.xml"
        }
      },
      "mainService_annotations": {
        "uri": "/sap/opu/odata/sap/API_EXAMPLE_SRV/$metadata/annotations",
        "type": "ODataAnnotation",
        "settings": {
          "localUri": "webapp/annotations/annotations_local.xml"
        }
      }
    }
  }
}
```

**STEP**: 3 — Overriding back end annotations: workflow and example

**DESCRIPTION**: To override an annotation defined in the back end:
1. Copy the back end annotation element(s) you want to change into a local annotation file in webapp/annotations/.
2. Keep the same Target and Qualifier (if present) and modify the annotation content locally.
3. The local annotation definition (same Target + same Qualifier + same Term) will override the back end one at runtime.
4. The order of multiple local annotation files and their overriding sequence is defined in manifest.json and can be viewed/changed in the annotation manager.

Use the XML snippet pattern below to create or modify annotation entries in webapp/annotations/*.xml.

**LANGUAGE**: XML

**CODE**:
```xml
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
  <edmx:DataServices>
    <Annotations Target="Namespace.EntityType">
      <!-- Example: overriding UI.LineItem with a Qualifier -->
      <Annotation Term="UI.LineItem" Qualifier="MyQualifier">
        <!-- content: e.g. Collection of DataField elements -->
        <Collection>
          <Record Type="UI.DataField">
            <PropertyValue Property="Label" String="Overridden Field"/>
            <PropertyValue Property="Value" Path="OverriddenProperty"/>
          </Record>
        </Collection>
      </Annotation>
    </Annotations>
  </edmx:DataServices>
</edmx:Edmx>
```

**STEP**: 4 — Tools and editor choices for maintaining annotations

**DESCRIPTION**: Choose the editor that fits your workflow:
- For direct XML editing with language server support: use the XML annotation language server (XML editor).
- For a schematic, visual editing experience: use the Page Editor (Annotation-based elements editor) or Service Modeler.
- Note: Service Modeler maintenance is applicable to OData services only — not for CAP CDS.

**LANGUAGE**: Text

**CODE**:
```text
Recommended options:
- XML language server: edit webapp/annotations/*.xml directly. Good for precise control.
- Page Editor (Annotation-based elements): visual editing in Fiori Tools for common patterns.
- Service Modeler: visualize annotations and manage OData annotations (not applicable to CAP CDS).

Important:
- Changes in local copies do not affect the deployed back end. To change behavior in your app, modify the local annotation files (webapp/annotations) and ensure manifest.json references them.
```

**STEP**: 5 — Verify override order and registration

**DESCRIPTION**: Confirm the overriding order and annotation registration:
- Check manifest.json to see the annotation files and their listed sequence.
- Use the annotation manager in Fiori Tools to view and change the overriding sequence if multiple local annotation files exist.

**LANGUAGE**: Text

**CODE**:
```text
- Open manifest.json and inspect "sap.app" -> "dataSources" entries for annotation files.
- If multiple local annotation files are used, the annotation manager (Service Modeler / annotation manager UI) shows and lets you reorder them.
- The first matching annotation (Target+Qualifier+Term) according to the manifest/manager order will be applied.
```

fiori-tools
annotations
OData
manifest.json
webapp/annotations
webapp/localService
override
Service Modeler