mcpField
S
sap-fiori-add-visual-filter

sap-fiori-add-visual-filter

github.com/sap开发161614 次安装今天更新
代码仓库

关于 sap-fiori-add-visual-filter

sap-fiori-add-visual-filter 用于为 SAP Fiori OData V4 应用添加柱形图或折线图可视筛选器,指导 CAP 与 ABAP RAP 实现,包括注解、manifest 配置、激活和验证。

主要功能

  1. 01添加柱形图或折线图筛选器
  2. 02配置 CAP 聚合和注解
  3. 03设置 ABAP RAP 图表注解
  4. 04配置 manifest 控制设置
  5. 05验证激活状态和 OData 元数据

适用场景

  1. 01为 CAP Fiori 应用添加图表筛选器
  2. 02在 ABAP RAP 应用中实现可视筛选器
  3. 03排查筛选器注解缺失或不匹配

MCP 相关

该技能要求在 VS Code 中使用 Fiori MCP Server 修改 Fiori 应用。对于 ABAP RAP,还说明使用 ABAP ADT MCP 激活 ABAP 对象。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sap/open-ux-tools --skill sap-fiori-add-visual-filter

安装后在 Claude Code 中输入/sap-fiori-add-visual-filter确认已加载。

详细介绍

SAP Fiori 可视化筛选器

用途

在筛选栏或值帮助对话框中添加基于图表的筛选器(柱状图/折线图)(OData V4)。


前提条件

CAP 项目:

  • ✅ VS Code 或 SAP Business Application Studio (BAS) - 两种环境均受支持
  • ✅ Fiori MCP Server - 修改 Fiori 应用所必需(仅限 VS Code)

ABAP RAP 项目:

  • ✅ 仅限 VS Code - ABAP Development Tools 扩展仅适用于 VS Code
  • ✅ Fiori MCP Server - 修改 Fiori 应用所必需
  • ✅ ABAP Development Tools for VS Code 扩展 - 后端开发所必需(包含用于 RAP 操作的 ADT MCP 服务)

必须:首先收集所需输入

如果提示中缺少以下任何输入,请停止并向用户询问所有这些输入:

  1. 实体 - 要添加可视化筛选器的实体
  2. 维度字段 - 用于筛选的字段(例如 Category、Status、Destination)
  3. 度量字段 - 要聚合的数值字段(例如 Amount、TotalPrice、ReservationPrice)
  4. 聚合方法 - 聚合方式(请参阅下方的有效值)
  5. 图表类型 - 柱状图或折线图(默认推荐柱状图)

在确认所有输入之前,请勿继续实施。

⚠️ 折线图维度类型限制: ChartType: #Line 仅支持类型为 Edm.Date、Edm.TimeOfDay 或 Edm.DateTimeOffset 的维度。如果请求的维度是其他类型(例如 Status、Category 等字符串/关联代码),请改用 #Bar,或先向用户确认该维度字段属于日期/时间类型,再继续操作。


CAP 实现

启用聚合(必须)
@Aggregation.ApplySupported: {
  Transformations: ['aggregate','groupby'],
  AggregatableProperties: [{ Property: Amount }],
  GroupableProperties: [Category]
}
聚合属性(度量)
Analytics.AggregatedProperty #Amount_sum : {
  $Type: 'Analytics.AggregatedPropertyType',
  Name: 'Amount_sum',
  AggregatableProperty: Amount,
  AggregationMethod: 'sum',
  ![@Common.Label]: 'Total Amount'
}

有效的 AggregationMethod 值(小写字符串):

  • sum - 非空值的总和
  • min - 非空值中的最小值
  • max - 非空值中的最大值
  • average - 非空值的总和除以非空值的数量
  • countdistinct - 非空值中不同值的数量

⚠️ 关键: 必须是小写字符串(例如 'sum'),不能是枚举(例如 #SUM)。使用枚举会导致 SQL 生成错误。

图表注解
UI.Chart #visualFilter : {
  ChartType: #Bar,
  Dimensions: [Category],
  DynamicMeasures: ['@Analytics.AggregatedProperty#Amount_sum']
}

✅ 使用 DynamicMeasures

PresentationVariant
UI.PresentationVariant #visualFilter: {
  Visualizations: ['@UI.Chart#visualFilter']
}
标量属性与受管关联维度

注解位置取决于维度在 CAP 模型中的声明方式:

  • 直接标量属性可以内联添加注解。例如,Category : String(80) 是一个实际的实体元素,因此应在 annotate ... with { ... } 块中使用 Category @Common.ValueList #visualFilter。
  • 受管关联则有所不同。例如,Category : Association to Categories 会生成本地外键 Category_code;Category_code 并非源实体中已声明的元素,因此无法在该块中内联添加注解。

对于标量 Category 维度,以下写法有效:

annotate MyService.Entity with {
  Category @Common.ValueList #visualFilter: {
    $Type: 'Common.ValueListType',
    CollectionPath: 'Entity',
    PresentationVariantQualifier: 'visualFilter',
    Parameters: [
      { $Type: 'Common.ValueListParameterInOut',
        LocalDataProperty: Category, ValueListProperty: 'Category' }
    ]
  };
};

如果可视化筛选器的维度是受管 Category 关联,请使用下文所述的单独关联键目标。不要在实体注解块中将目标替换为 Category_code。

⚠️ 维度是托管关联外键(例如 Category_code、Status_ID)

当维度字段是托管关联自动生成的外键列时(例如,来自 Category : Association to Categories 的 Category_code),不能在实体的 annotate ... with { ... } 块中内联添加注解——该处无法看到外键列。CDS 编译器会报错:

Element "Category_code" has not been found

✅ 正确: 使用单独的 annotate 语句,并以关联本身为目标——编译器会将其重写到外键列:

// Compiles to target Travels/Category_code in $metadata
annotate MyService.Entity:Category with @(
  Common.ValueList #visualFilter: {
    $Type                       : 'Common.ValueListType',
    CollectionPath              : 'Entity',
    PresentationVariantQualifier: 'visualFilter',
    Parameters                  : [
      { $Type: 'Common.ValueListParameterInOut',
        LocalDataProperty: Category_code, ValueListProperty: 'Category_code' }
    ]
  }
);

要点:

  • 目标语法:annotate <Service>.<Entity>:<assoc>——对于托管的一对一关联,编译器会将关联上的注解复制/重写到其生成的本地外键元素。这符合文档所述的 CAP 编译器行为(参见 CAP 文档中的“Managed Associations”)。如果其他注解(例如 Common.Label、Common.Text)已在其他位置以同一关联为目标,它们会在 $metadata 中合并到单个 Annotations Target="...Entity/<assoc>_code" 块中。如有疑问,请使用 cds compile --to edmx 验证。
  • LocalDataProperty 和 ValueListProperty 都使用外键列名称(例如 Category_code),而不是关联名称。
  • CollectionPath 是包含图表数据的同一个实体集(自引用),而不是代码列表实体集。

❌ 错误: 在实体块中内联添加注解——无法编译:

annotate MyService.Entity with { ... } {
  Category_code @Common.ValueList #visualFilter: { ... };  // ❌ Element not found
};
SelectionFields
UI.SelectionFields: [Category]
Manifest 配置(强制要求)

下方的共享 Manifest 配置部分适用于 CAP 和 RAP。

ABAP RAP 实现(4 个步骤)

关键:绝不编辑 metadata.xml——它是只读文件!
⚠️ 实施前检查清单——验证后再实施

以下任意一项缺失都会导致可视化筛选器失效:

  • 在投影视图(ZC_*)上设置 @OData.applySupportedForAggregation: #FULL
  • 在度量字段上设置 @Aggregation.default: #SUM(或 #AVG、#MIN、#MAX)
  • 在元数据扩展中设置带正确限定符的 @UI.chart 注解
  • 在维度字段上设置 @UI.selectionField
  • 在 annotation.xml 中添加前端 Common.ValueList 注解
  • 在 Manifest 中设置带可视化筛选器设置的 controlConfiguration
  • 激活所有 CDS 对象

1. 后端投影视图(强制要求)——启用聚合支持

⚠️ 关键:必须设置 @OData.applySupportedForAggregation 注解

未设置此注解时:

  • OData 服务将不支持聚合
  • 可视化筛选器将无法加载
  • 图表注解将被忽略

设置位置:

  • ✅ 必须设置在投影视图(ZC_* 或 ZZZC_*)上,并使用 TRANSACTIONAL_QUERY 契约
  • ❌ 不得设置在接口视图(ZR_* 或 ZZZR_*)上

正确示例:

// MANDATORY! Must be present!
@OData.applySupportedForAggregation: #FULL
define root view entity ZC_ENTITY
  provider contract TRANSACTIONAL_QUERY
  as projection on ZR_ENTITY
{
  @Aggregation.default: #SUM  // Specify aggregation method for measure
  Amount;
  Category;  // Dimension field (no aggregation annotation needed)
}

错误示例:

// ❌ WRONG - Don't put on interface view
// WRONG PLACE!
@OData.applySupportedForAggregation: #FULL
define root view entity ZR_ENTITY
  as select from TABLE
2. 后端元数据扩展(强制要求)——添加 Chart、PresentationVariant 和 SelectionField 注解

⚠️ 关键:@UI.chart 和 @UI.presentationVariant 是实体级(标头)注解。 将它们放在标头块中——位于 annotate view ZC_ENTITY with 之前(与 @UI.headerInfo.* 并列),不要放在 { ... } 字段块中,也不要放在字段上(例如维度字段)。 将 @UI.chart 附加到字段会导致激活失败,并报错:Annotation 'UI.chart.qualifier' used at wrong position (wrong scope)。

// ↓↓↓ HEADER SCOPE: these go BEFORE `annotate view`, never on a field ↓↓↓
@UI.chart: [{
  qualifier: 'visualFilter',
  chartType: #BAR,
  dimensions: ['Category'],
  measures: ['Amount']
}]
@UI.presentationVariant: [{
  qualifier: 'visualFilter',
  visualizations: [{
    type: #AS_CHART,
    qualifier: 'visualFilter'
  }]
}]
annotate view ZC_ENTITY with
{
  @UI.selectionField: [{ position: 10 }]
  Category;

  @EndUserText.label: 'Amount'
  Amount;
}
3. 前端(annotation.xml)——添加 ValueList

维度字段上的 ValueList 注解:

<Annotations Target="<YourServiceNamespace>.<YourEntityType>/Category">
  <Annotation Term="Common.ValueList" Qualifier="visualFilter">
    <Record Type="Common.ValueListType">
      <PropertyValue Property="CollectionPath" String="<YourEntitySet>"/>
      <PropertyValue Property="PresentationVariantQualifier" String="visualFilter"/>
      <PropertyValue Property="Parameters">
        <Collection>
          <Record Type="Common.ValueListParameterInOut">
            <PropertyValue Property="LocalDataProperty" PropertyPath="Category"/>
            <PropertyValue Property="ValueListProperty" String="Category"/>
          </Record>
        </Collection>
      </PropertyValue>
    </Record>
  </Annotation>
</Annotations>

重要: 替换占位符:

  • <YourServiceNamespace> - 例如,com.sap.gateway.srvd.ztravel.v0001
  • <YourEntityType> - 例如,TravelType
  • <YourEntitySet> - 例如,Travel
4. 验证激活的注解(必须)

激活 DDLS 和 DDLX 后,验证更改已生效:

⚠️ 重要:DDLS 和 DDLX 是不同的对象

投影视图(DDLS 文件)和元数据扩展(DDLX 文件)是两个独立的 ABAP 开发对象,只是实体名称相同。

要点:

  • DDLS = 数据定义(投影视图)——包含实体定义、关联、字段和数据注解
  • DDLX = 元数据扩展——包含 UI 注解(@UI.chart、@UI.presentationVariant、字段标签等)
  • 两者必须分别激活——激活其中一个不会激活另一个
  • 两者都必须存在,视觉筛选器才能正常工作

激活:

  • 使用 ABAP ADT MCP 激活 ABAP 对象
  • 将 DDLS 文件和 DDLX 文件分别激活

验证步骤:

  1. 验证激活状态:

    • 检查激活工具输出中是否有成功消息
    • 确认激活过程中没有报告错误
    • DDLS 和 DDLX 都必须显示已成功激活
  2. 检查 OData $metadata:

    • 在浏览器中打开服务 URL:<service-url>/$metadata
    • 搜索:<Annotation Term="UI.Chart" Qualifier="visualFilter">
    • 同时验证:<Annotation Term="UI.PresentationVariant" Qualifier="visualFilter">
    • 如果 $metadata 中缺少这些注解,则表示 DDLX 未激活,或者需要重新发布服务绑定
5. Manifest 配置(必须)

使用下方的共享 Manifest 配置部分。


Manifest 配置(CAP 和 RAP 通用)

完整的 manifest.json 结构:

"sap.ui5": {
  "routing": {
    "targets": {
      "<YourListReport>": {  // Replace with your actual List Report target name
        "type": "Component",
        "name": "sap.fe.templates.ListReport",
        "options": {
          "settings": {
            "contextPath": "/<YourEntitySet>",  // Replace with your entity set path
            "controlConfiguration": {
              "@com.sap.vocabularies.UI.v1.SelectionFields": {
                "layout": "CompactVisual",
                "initialLayout": "Visual",
                "filterFields": {
                  "Category": {
                    "visualFilter": {
                      "valueList": "com.sap.vocabularies.Common.v1.ValueList#visualFilter"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

路径: sap.ui5.routing.targets.<ListReport>.options.settings.controlConfiguration 视觉筛选器设置应放在 controlConfiguration 下,而不是直接放在 settings 下。

重要占位符:

  • <YourListReport> - 你的列表报告目标名称(例如,TravelList)
  • <YourEntitySet> - 你的实体集路径(例如,/Travel)
  • Category - 你的维度字段名称
  • visualFilter - 必须与注解中的限定符一致

重要:Manifest 配置结构

视觉筛选器设置应放在 controlConfiguration 下,不能直接放在 settings 下!


测试

有关详细的测试说明,请参阅 sap-fiori-app-development 技能中的应用预览指南部分,其中包括:

  • 使用监视脚本测试 CAP 项目
  • 使用实时后端与模拟模式测试独立 Fiori 项目
  • 后端更改后的元数据刷新流程

主要区别

CAP:

  • 在 CDS 中定义聚合和度量
  • 使用 DynamicMeasures
  • 在同一位置定义聚合和图表

RAP:

  • 仅在后端 CDS 中定义聚合
  • 使用 Measures(而不是 DynamicMeasures)
  • 元数据为只读

常见错误

  • 后端更改未激活。
  • Chart、ValueList、PresentationVariant 和 manifest 之间的限定符不匹配
  • manifest 中的路径错误(使用完整的词汇路径)
  • 缺少 SelectionField 注解
  • 度量字段不是数值类型
  • manifest 中缺少紧凑型视觉布局配置

CAP:

  • 尝试在 annotate ... with { ... } 中内联注解托管关联的外键列(例如 Status_code)——会出现 Element "..._code" has not been found 错误。请改用单独的 annotate Service.Entity:assoc with (...) 语句(参见上文“维度是托管关联外键”)。

RAP:

  • 缺少后端聚合支持
  • 使用 DynamicMeasures 而不是 Measures
  • 在后端而不是前端添加 Common.ValueList(ValueList 必须放在前端 annotation.xml 中)
  • 直接在 CDS 投影视图中添加 UI 注解,而不是添加到元数据扩展中
  • 尝试使用 @Consumption.valueHelpDefinition 实现视觉筛选器(该注解用于值帮助对话框,而非视觉筛选器)

最佳实践

  • 测试前,务必在 ADT MCP 中激活后端更改
  • 每个可视化筛选器使用 1 个维度 + 1 个度量
  • 优先使用柱状图,以提高可读性
  • 在所有注解中保持限定符名称一致
  • 使用不同的数据量进行测试
  • 务必在清单中包含 layout: "CompactVisual" 和 initialLayout: "Visual"

RAP 特定说明:

  • 有条件时,务必使用 ADT MCP 修改后端文件
  • 图表 + PresentationVariant → 后端元数据扩展(.ddlx.acds)
  • Common.ValueList → 前端 annotation.xml(不能位于后端)

参考资料

评论

支持 Markdown