https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/SAPUI5-blog-posts.xmlSAP Community - SAPUI52026-04-23T02:01:29.800926+00:00python-feedgenSAPUI5 blog posts in SAP Communityhttps://community.sap.com/t5/frontend-ui5-sap-fiori-blog-posts/problems-hiding-and-showing-table-columns/ba-p/14327225Problems hiding and showing table columns2026-02-12T15:00:28.444000+01:00Andrei_Lysakhttps://community.sap.com/t5/user/viewprofilepage/user-id/2101129<P>Hello experts, I have a problem.<BR />I need to hide table columns based on certain conditions.<BR />I get the table object by ID and then all the columns.<BR />Then I use oColumn.setVisible(), and everything works. However, the problem is that in the table personalization, this column is marked as selected, with a check mark.<BR />Is it possible to affect the table settings after changing the column properties?<BR />All tables are described on the backend and Table Type </P><DIV><DIV><SPAN>ResponsiveTable(sap.ui.mdc.table)</SPAN></DIV></DIV>2026-02-12T15:00:28.444000+01:00https://community.sap.com/t5/sap-community-leaders-finder/gregor-wolf/ba-p/14334595Gregor Wolf2026-02-23T18:24:58.182000+01:00StephanieMarleyhttps://community.sap.com/t5/user/viewprofilepage/user-id/109<P class=""><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/12545" target="_self">About Gregor</A></P>
<UL>
<LI><FONT face="tahoma,arial,helvetica,sans-serif">Germany | </FONT><FONT face="tahoma,arial,helvetica,sans-serif">SAP Mentor since 2007 | </FONT><FONT face="tahoma,arial,helvetica,sans-serif">Follow Gregor on <A href="https://www.linkedin.com/in/gregorwolf/" target="_self" rel="nofollow noopener noreferrer">LinkedIn</A></FONT></LI>
</UL>
<P><STRONG><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="gregor.jpg" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/375814i2FFBF9F0A61929ED/image-size/small?v=v2&px=200" role="button" title="gregor.jpg" alt="gregor.jpg" /></span></STRONG><SPAN>I am an independent SAP solution architect, developer and SAP Mentor. I focus on SAP Business Technology Platform, SAP Cloud Application Programming Model (CAP), Node.JS, SAP Fiori Elements and Security. I've supported several customers during their SAP Cloud ERP Private Edition (S/4HANA On Premise) implementation. Since the end of 2024 I support the technical topics at an SAP Cloud ERP Public Edition Customer.</SPAN></P>
<P><FONT face="tahoma,arial,helvetica,sans-serif"><STRONG>Topics of interest: </STRONG></FONT>SAP Business Technology Platform, SAP Cloud Application Programming Model (CAP), SAP Cloud ERP public and private, SAPUI5, OpenUI5, SAP Fiori, SAP HANA Cloud</P>
<P><FONT face="tahoma,arial,helvetica,sans-serif"><STRONG>Gregor, what inspired you to become an SAP Mentor?</STRONG></FONT></P>
<P><FONT face="tahoma,arial,helvetica,sans-serif"><STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="handshake .png" style="width: 68px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/52491i8E9D2FFB3C7BC293/image-dimensions/68x68?v=v2" width="68" height="68" role="button" title="handshake .png" alt="handshake .png" /></span></STRONG></FONT>A key influence early in my SAP Community journey was Mark Finnern. He is the father of the SAP Community. Mark encouraged me to move beyond answering questions and start sharing detailed technical how-to's but also event reports in blog posts. In 2007 Mark also founded the SAP Mentors program which gave me the opportunity to provide structured, experience-based feedback to SAP product teams and help bridge the gap between product vision and real-world implementation.</P>
<P><FONT face="tahoma,arial,helvetica,sans-serif"><STRONG>What advice would like to share with other SAP community members?</STRONG></FONT></P>
<P><FONT face="tahoma,arial,helvetica,sans-serif"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="298874_collaborate_blue (1).png" style="width: 65px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/52495i64D82195EFF8CCB9/image-dimensions/65x65?v=v2" width="65" height="65" role="button" title="298874_collaborate_blue (1).png" alt="298874_collaborate_blue (1).png" /></span></FONT>My advice to other SAP Community members is simple: contribute consistently and think long-term.</P>
<P>Start by answering questions and helping others solve real problems - but don’t stop there. Document your lessons learned, share architectural insights, and write about what worked and what didn’t. That’s how collective expertise grows. And you will be amazed how often you research years later and find your own answers and blog posts to solve a problem you're just facing. Despite all the new stuff SAP has quite a long tail that doesn't change quickly.<BR /><BR />Engage constructively, challenge respectfully, and focus on signal over noise. The community is not just a support forum - it’s an ecosystem where practitioners can influence product direction, elevate standards, and shape the future of SAP together.</P>2026-02-23T18:24:58.182000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/configure-your-sap-fiori-elements-apps-introducing-fine-tuning-in-the-sap/ba-p/14335492Configure Your SAP Fiori Elements Apps: Introducing Fine-Tuning in the SAP Fiori Development Portal2026-02-24T13:45:32.257000+01:00marcel_waechterhttps://community.sap.com/t5/user/viewprofilepage/user-id/302397<P>Throughout our blog series on the SAP Fiori development portal, we've explored how SAP Fiori elements leverages metadata and annotations to build enterprise-grade UIs following the Global UX design principles. But what happens when you need to adjust UI behavior in ways that aren't expressed through annotations? That's what we call configuration – and the Fiori tools are the best place for it. But we're excited to introduce a new feature in the SAP Fiori development portal that makes configuration discovery and experimentation easier than ever.</P><H2 id="toc-hId-1790537243">Understanding Fine-Tuning in SAP Fiori Elements</H2><P>SAP Fiori elements applications are primarily driven by metadata and annotations - this is their superpower. Annotations define what data to display, how to structure it, and which features to enable. However, not every UI behavior can or should be controlled through annotations. Some aspects require configuration settings that fine-tune how building blocks render and behave.</P><P>Let's take the table building block as a perfect example. When you annotate your service with UI.LineItem, SAP Fiori elements automatically selects an appropriate table type based on your entity's capabilities and the Global UX design guidelines:</P><UL><LI>If your entity set is analytics-enabled, an Analytical Table is displayed, providing built-in aggregation and grouping capabilities</LI><LI>For standard use cases, the Responsive Table is shown by default - it's optimized for various screen sizes and delivers the best user experience across devices</LI><LI>But what if you need to display massive datasets where scrolling performance is critical? The Grid Table excels at rendering huge amounts of data efficiently</LI></UL><P>Here's the challenge: there's no annotation to switch between these table types. This is where fine-tuning comes into play. You configure these settings in your application's manifest.json or directly in the building block definition when using XML views. But how do you discover what's configurable? What are the available options? What values can you set?</P><H2 id="toc-hId-1594023738">Introducing the Fine-Tuning Panel in the SAP Fiori Development Portal</H2><P>The SAP Fiori development portal now includes a dedicated Fine-Tuning panel that answers these questions interactively. When you open the code editor for any building block - let's use the table as our example - you'll notice two tabs at the top: "Code" and "Fine-Tuning."</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Fine-Tuning Panel" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/376360i2523445F880F12BE/image-size/large?v=v2&px=999" role="button" title="marcel_waechter_0-1771936151776.png" alt="Fine-Tuning Panel" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Fine-Tuning Panel</span></span></P><P>The Fine-Tuning panel reveals all available configuration settings for the building block, complete with:</P><UL><LI>Clear descriptions explaining what each setting controls</LI><LI>The current value applied in the sample</LI><LI>A searchable interface to quickly find specific settings</LI><LI>Immediate visual feedback when you change values</LI></UL><H2 id="toc-hId-1397510233">Exploring Fine-Tuning: A Table Story</H2><P>Let's walk through a practical scenario. Navigate to the <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/table/tableDefault" target="_blank" rel="noopener noreferrer">Table Building Block</A> in the SAP Fiori development portal and click "Show Code" to open the code editor. Now switch to the "Fine-Tuning" tab.</P><P>You'll see a comprehensive list of configuration options. Let's say you're working on an application that needs to display thousands of travel records, and scrolling performance is becoming an issue. You remember hearing about the Grid Table's superior performance with large datasets, but you're not sure how to enable it.</P><P>In the Fine-Tuning panel, use the search box and type "type." The list immediately filters to show the "type" setting, which controls the table visualization. You'll see:</P><UL><LI>A description explaining the table type setting</LI><LI>The current value: "ResponsiveTable" (the default)</LI><LI>A dropdown showing all available options: ResponsiveTable, GridTable and AnalyticalTable</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Searching for settings" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/376359i05839421B654A218/image-size/large?v=v2&px=999" role="button" title="marcel_waechter_1-1771936151777.png" alt="Searching for settings" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Searching for settings</span></span></P><P>Change the value to "GridTable" and watch the magic happen. The preview immediately updates, showing your table rendered as a Grid Table.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Changing the table type" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/376358i2E93AA7F66D5950B/image-size/large?v=v2&px=999" role="button" title="marcel_waechter_2-1771936151777.png" alt="Changing the table type" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Changing the table type</span></span></P><P>You can see the visual differences</P><UL><LI>the denser layout</LI><LI>the different scrolling behavior</LI><LI>the optimized rendering for large datasets</LI></UL><P>But here's where it gets even better. Switch back to the "Code" tab, and you'll notice the code has been automatically updated:<BR /><BR /></P><pre class="lia-code-sample language-markup"><code><core:FragmentDefinition
xmlns:core="sap.ui.core"
xmlns="sap.m"
xmlns:macros="sap.fe.macros">
<macros:Table metaPath="/Travel/@com.sap.vocabularies.UI.v1.LineItem" type="GridTable"/>
</core:FragmentDefinition></code></pre><P>The `type="GridTable"` attribute has been added automatically. If you're using building blocks directly in your XML views, you can simply copy this code into your application. Perfect for custom page development!</P><H2 id="toc-hId-1200996728">From Exploration to Implementation</H2><P>The Fine-Tuning panel serves as your bridge from exploration to implementation. You can experiment with different settings, understand their effects, and see the exact code needed - all in one interactive environment.</P><P>However, it's important to understand where these settings belong in your application architecture:</P><UL><LI><STRONG>For Building Blocks in XML Views</STRONG> (like in custom pages): Apply the settings directly as attributes on the building block, just as shown in the code editor. The portal gives you the exact syntax you need.</LI><LI><STRONG>For Standard Floorplans </STRONG>(List Report, Object Page, etc.): The table building blocks are already integrated into the page structure. To fine-tune them, you add configuration settings to your application's manifest.json file. The SAP Fiori tools Page Map provides a user-friendly interface for configuring these settings without manually editing JSON.</LI></UL><P>This two-path approach ensures you can fine-tune your application whether you're building custom pages with building blocks or extending standard floorplans.</P><H2 id="toc-hId-1004483223">The Fiori Development Portal as Your Fine-Tuning Laboratory</H2><P>Think of the SAP Fiori development portal's Fine-Tuning panel as your laboratory for configuration experimentation. You can:</P><UL><LI>Discover settings you didn't know existed</LI><LI>Understand the purpose and impact of each configuration option</LI><LI>Test different combinations to find the optimal setup for your requirements</LI><LI>Learn the exact syntax needed for implementation</LI><LI>Make informed decisions backed by visual evidence</LI></UL><P>This interactive approach transforms configuration from a trial-and-error process into a guided, informed decision-making experience.</P><P><STRONG>But keep in mind</STRONG>: SAP Fiori elements applies Global UX design principles automatically. Only fine-tune when you have specific requirements that justify deviating from the defaults.</P><H2 id="toc-hId-807969718">What's Next</H2><P>The Fine-Tuning panel represents another step in our commitment to making SAP Fiori elements development more accessible, efficient, and collaborative. But we're not stopping here. We have exciting enhancements planned that will further improve your development experience with the SAP Fiori development portal.</P><P>Stay tuned for upcoming blog posts where we'll introduce additional features that continue to bridge the gap between exploration and implementation, making your journey from concept to production even smoother.</P><P>To get the full overview of the SAP Fiori development portal, check out the following blog posts of the mini-series:</P><UL class=""><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-sap-fiori-development-portal-your-gateway-to-rapid-sap/ba-p/14236768" target="_blank">Introducing the SAP Fiori Development Portal: Your Gateway to Rapid SAP Fiori App Creation (1 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/get-familiar-with-sap-fiori-development-portal-and-the-power-of-the/ba-p/14240041" target="_self">Get familiar with SAP Fiori development portal and the power of the building blocks (2 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/explore-the-potential-of-sap-fiori-development-portal-using-complex/ba-p/14257622" target="_self">Explore the potential of SAP Fiori development portal using complex building blocks (3 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/use-sap-fiori-development-portal-to-understand-extension-options-for/ba-p/14270914" target="_self">Use SAP Fiori development portal to understand extension options for standard floorplans (4 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/prepare-building-custom-pages-by-using-sap-fiori-development-portal-5-of-6/ba-p/14277842" target="_self">Prepare building custom pages by using SAP Fiori development portal (5 of 6)</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/bringing-the-sap-fiori-development-portal-and-its-use-to-the-next-level-6/ba-p/14285025" target="_self">Bringing the SAP Fiori development portal and its use to the next level (6 of 6)</A></LI></UL>2026-02-24T13:45:32.257000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/customize-sapui5-apps-for-business-users-make-an-impact-by-joining-our-cei/ba-p/14337265Customize SAPUI5 apps for business users – make an impact by joining our CEI project2026-03-01T19:15:53.813000+01:00storkdhttps://community.sap.com/t5/user/viewprofilepage/user-id/687415<P>SAP Customer Engagement Initiatives (CEI) on <SPAN><A href="https://influence.sap.com/" target="_blank" rel="noopener noreferrer">https://influence.sap.com</A></SPAN> allow you, as an SAP customer or partner, to gain early insights into SAP's product developments and work directly with SAP teams to shape future product directions. This project presents a unique opportunity to work with SAPUI5 flexibility product managers and engineering teams, leveraging your expertise customizing SAPUI5 apps with key user adaptation.</P><P><STRONG>Join the upcoming CEI project to make an impact on how key users interact with key user adaptation</STRONG></P><P>If you’re already convinced – <A href="https://influence.sap.com/sap/ino/#campaign/4163" target="_blank" rel="noopener noreferrer">join here</A>. If not, read on <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span></P><P><STRONG>What is key user adaptation? </STRONG></P><P>Key user adaptation is a mode that allows extending SAPUI5 applications for other users right in the browser. It is highly intuitive and requires no technical or programming skills. <SPAN>J</SPAN>ust use drag and drop to make UI changes – no modification or copy of SAP standard coding necessary! Read more <A href="https://help.sap.com/docs/UI5_FLEXIBILITY/430e2c1a4ff241bc8162df4bf51e0730/328a550137344514ae085b924180d078.html?language=en-US&locale=en-US" target="_blank" rel="noopener noreferrer">here</A>.</P><P><STRONG>What is the targeted improvement?</STRONG></P><P>Although the product is mature and widely used, we actively evolve it by delivering new functionality and capability enhancements alongside continuous user experience improvements, informed by UI testing and direct customer feedback. </P><P>We are in the process of overhauling key user adaptation’s UI, simplifying the overall approach while making often-used scenarios more streamlined. We’ve taken a close look at the version history (of activated adaptations) and how our users interact with it, extended the “embed third-party content” feature, widened the scope of custom fields that can be added to the UI – and more.</P><P>To ensure that we are on the right way, we need your help!</P><P><STRONG>Who should participate?</STRONG></P><P>Users who want to adapt standard SAPUI5 apps for business users. Both key users and technical users are welcome.</P><P><STRONG>Why should you participate?</STRONG></P><UL><LI>Gain understanding of SAPUI5 flexibility</LI><LI>Chance to influence a central SAPUI5 feature</LI><LI>Early access to prototypes</LI></UL><P><STRONG>How can you participate?</STRONG></P><P>Don’t miss out on this opportunity to share your feedback and engage with SAPUI5 flexibility development teams. Register by <STRONG>March 15, 2026</STRONG>, and make a true impact on how you can customize SAP apps to your needs!</P><P>Click<SPAN> </SPAN><U><A href="https://influence.sap.com/sap/ino/#campaign/4163" target="_blank" rel="noopener noreferrer">here</A></U> to sign up for our project. (A short overview about how to get started on<SPAN> </SPAN><U><A href="https://pages.community.sap.com/topics/influence-adopt" target="_blank" rel="noopener noreferrer">influence.sap.com</A></U> can be found<SPAN> </SPAN><U><A href="https://d.dam.sap.com/a/ZL5Rg8j/Get%20Started%20and%20Navigate%20the%20Customer%20Influence%20Site_2024.pdf?rc=10" target="_blank" rel="noopener noreferrer">here</A></U>).</P><P>After you register for a project, you will be invited to an introductory call where you will get more information. This call is followed by individual or grouped feedback sessions.</P><P>Thank you in advance for helping us shape the future of SAPUI5 flexibility!</P>2026-03-01T19:15:53.813000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/ui5con-bengaluru-2026-community-code-and-the-future-of-sap-ui-development/ba-p/14340524UI5con Bengaluru 2026 - Community, Code, and the Future of SAP UI Development2026-03-03T12:16:36.382000+01:00freddy_jetty_johnsonhttps://community.sap.com/t5/user/viewprofilepage/user-id/606671<P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="freddy_jetty_johnson_0-1772531004884.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379114i61E092BC659BC171/image-size/large?v=v2&px=999" role="button" title="freddy_jetty_johnson_0-1772531004884.jpeg" alt="freddy_jetty_johnson_0-1772531004884.jpeg" /></span></P><P>UI5con Bengaluru 2026 brought together 400+ developers, architects, consultants, and students from across India for a full day of learning, hands-on exploration, and community connection. Held at the SAP Labs campus in Devanahalli as part of SAP Inside Track Bengaluru 2026, the event marked a historic double first — the first time UI5con has taken place in India in seven years, and the very first SAP Inside Track and UI5con held jointly at this location. The event covered everything from the cutting-edge world of AI-assisted development to the fundamentals of accessibility and enterprise UX — all through the lens of SAPUI5 and SAP Fiori.</P><P>This was more than a conference; it was a homecoming. With UI5con returning to India after seven years and joining forces with SAP Inside Track for the very first time, the energy in the room was something special — a community reunited and ready to build.</P><P class="lia-align-center" style="text-align: center;"><FONT size="2" color="#333333"><EM>"It's my first SAP Inside Track session as an ABAP Fiori developer. I had a great session attending UI5con. Learned some amazing things during the session."<BR /></EM><STRONG>Participant, Deloitte USI</STRONG></FONT></P><H1 id="toc-hId-1662229836">Kickoff: Agentic Coding with UI5 — From Idea to Inclusive App</H1><P>Stefan Beck, Peter Muessig, and Rajashree Raghavendra opened the day with a keynote that was equal parts history lesson and vision statement — reminding the audience that UI5con Bengaluru began in 2018, grew to 400+ attendees, 28 sessions, and 41 speakers in 2019, and is now back after a COVID-forced pause of seven years. They traced SAPUI5’s journey from its 2012 enterprise foundations to its current form: TypeScript, Web Components, CI/CD, and a 90% accessibility score in the Web Almanac 2025. Two strategic bets anchored the roadmap: UI5 Web Components (framework-free, standards-based) and Legacy-Free OpenUI5/SAPUI5 (deprecated code removed, async by default).</P><P>The AI portion of the keynote charted the evolution from basic code completion in 2020 to the agentic coding era of today and introduced the UI5 MCP Server and Fiori MCP Server as the practical bridges between AI tools and SAP development best practices. A live demo closed the session — an inclusive app built from scratch using Fiori elements Building Blocks and Freestyle code, guided by agentic AI in real time. The vision set the tone for everything that followed: <EM>"UI5 in 2026 is where AI acceleration, inclusive design, and enterprise trust meet."</EM></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="1 (1).jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379174iE3A342E08BB18E81/image-size/large?v=v2&px=999" role="button" title="1 (1).jpg" alt="1 (1).jpg" /></span></P><H1 id="toc-hId-1465716331"><SPAN>AI Takes Centre Stage</SPAN></H1><P>If there was one theme that ran through every session at UI5con 2026, it was AI — and not just as a buzzword. The hands-on session on the MCP Server for Fiori, led by Vinay Hospete, Ashish Anand, and Maheeth Reddy, introduced attendees to the Model Context Protocol — the emerging standard that connects AI coding agents to domain-specific tools and best practices. The demo pod on Vibe Coding with SAP UI5 brought this to life, showing how natural language prompts combined with Cline and SAP AI Core enable governed, auditable UI5 app generation — where AI accelerates the work, but the developer stays in control.</P><P class="lia-align-center" style="text-align: center;"><FONT size="2" color="#333333"><EM>"Vibe coding: Using the MCP server, the code can be generated quickly and can be adapted for the demo & quick mockup."<BR /></EM></FONT><FONT size="2" color="#333333"><STRONG>Participant, Nokia</STRONG></FONT></P><H1 id="toc-hId-1269202826">Deep Dives: Going Beyond the Basics</H1><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="2.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379175i34A3DD59548CE1D4/image-size/large?v=v2&px=999" role="button" title="2.jpg" alt="2.jpg" /></span></P><P>The deep dive track gave attendees space to go further. Merlin Beutlberger's UI5 in the World of AI showcased the UI5 MCP Server's 10 tools — from app creation and API reference lookups to Linter runs and TypeScript migration guides — with a live demo of an AI agent building a full UI5 app from a natural language prompt. Jitendra Kansal's MDK session addressed how to bring Fiori to mobile without a rewrite, with the MDK MCP Server intelligently transforming UI for smaller screens. Mohammed Sijas introduced the DataRepository library, a lightweight solution that brings OData-like CRUD convenience to plain REST APIs.</P><P>Sandeep R S and Vinay Hospete reinforced that ~90% of SAP's own SAPUI5 apps are built on Fiori elements, and that MCP-powered agentic AI is the natural next step. Syed's session on Fiori Applications Demystified gave backend developers and architects a grounding in MVC, bindings, and when to choose Freestyle over Fiori Elements.</P><P class="lia-align-center" style="text-align: center;"><FONT size="2"><EM>"Good place to know what's new and what is the future scope. Hands-on sessions give good insight on the topics."<BR /></EM><STRONG>Participant, Cargill</STRONG></FONT></P><H1 id="toc-hId-1072689321">Accessibility, Web Components, and More</H1><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="3.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379177i7675E74EF7261C46/image-size/large?v=v2&px=999" role="button" title="3.jpg" alt="3.jpg" /></span></P><P>Gergana Georgieva's session on UI5's Ever-Evolving Accessibility was a highlight for many attendees. She walked through SAP's commitment to WCAG 2.2 and ARIA 1.2 standards, covering everything from keyboard navigation and screen reader support to the new Target Size requirements. The key message: accessibility requires both framework support and developer discipline — it must become a habit, not an afterthought.</P><P class="lia-align-center" style="text-align: center;"><FONT size="2"><EM>"I really liked the accessibility session."<BR /></EM></FONT><FONT size="2"><STRONG>Participant, Wipro</STRONG></FONT></P><P>The demo pod on UI5 Web Components — presented by Rounak, Vignesh, and Dharshini — showcased the growing maturity of the framework-agnostic component library built on web standards. Web Components 2.0 was announced, with new components including the intriguing <ui5-ai-button>. For developers working with React, Angular, or Vue, this opens new doors.</P><P class="lia-align-center" style="text-align: center;"><FONT size="2"><EM>"It was very interactive. Now they are releasing web components 2.0 which looks promising."<BR /></EM></FONT><FONT size="2"><STRONG>Participant, Adidas</STRONG></FONT></P><P>The Suite Controls session from Ashwin Kumar Bolar, Vinay K N, and Santhosh covered enterprise-grade components for complex business applications: Network Graph, UploadSetWithTable, and the Gantt Chart — each purpose-built for the kind of rich operational dashboards that SAP customers depend on. Kotresh T M rounded out the day with a deep dive into cross-app navigation for Fiori microfrontends, making the case for intent-based navigation as the standard pattern for loosely coupled Fiori apps.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="4.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379179iFE6FE3D6DCC7DC37/image-size/large?v=v2&px=999" role="button" title="4.jpg" alt="4.jpg" /></span></P><P> <SPAN>And for those excited about the future of AI in SAP applications, Arun Bharathi K's demo on Joule Frontend Actions showed how UI5 apps can expose capabilities directly to SAP's digital AI assistant — making Joule a conversational interface for everyday Fiori interactions.</SPAN></P><P class="lia-align-center" style="text-align: center;"><FONT size="2"><EM>"Got to know about the capability of Joule with the frontend actions. Would like to have a blog on this."<BR /></EM></FONT><FONT size="2"><STRONG>Participant, AMGBT</STRONG></FONT></P><H1 id="toc-hId-876175816">Hands-On Sessions: Learning by Doing</H1><P>A major draw of UI5con has always been its hands-on sessions — and 2026 was no exception. Attendees rolled up their sleeves and built real UI5 apps, working through exercises on SAP Fiori elements V4, the Flexible Programming Model, and the UI5 Linter, with GitHub repositories shared so participants could take the work home. Volunteers circulated the room throughout, ensuring no one got stuck, and the atmosphere — equal parts focused and buzzing — was one of the highlights of the day.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="5.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379180iF73A58EBB841807C/image-size/large?v=v2&px=999" role="button" title="5.jpg" alt="5.jpg" /></span></P><P class="lia-align-center" style="text-align: center;"><FONT size="2"><EM>“Attended 2 hands-on sessions of UI5con. Volunteers are always ready to help, amazing knowledgeable speakers. Loved the UI5con event.”<BR /></EM></FONT><FONT size="2"><STRONG>Participant, Deloitte</STRONG></FONT></P><H1 id="toc-hId-679662311">Ask the Expert: The Closing Highlight</H1><P>The day closed with one of its most anticipated moments: the Ask the Expert panel. Peter Muessig, Vinod S Nair, Stefan Beck and Sandeep R S — some of the most prominent names behind UI5 and SAP Fiori — took to the stage together for an open, free-flowing conversation with the audience. The session was part Q&A, part fireside chat, and completely candid. Attendees asked about the roadmap, the future of legacy migrations, how best to adopt agentic AI in their own teams, and much more. It was exactly the kind of direct access to the people building the platform that makes UI5con special — and a fitting send-off for the day.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="freddy_jetty_johnson_11-1772531004946.jpeg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379124iA58C1C7F34E62993/image-size/large?v=v2&px=999" role="button" title="freddy_jetty_johnson_11-1772531004946.jpeg" alt="freddy_jetty_johnson_11-1772531004946.jpeg" /></span></P><H1 id="toc-hId-483148806">The Community Makes the Event</H1><P>Across the feedback forms, one theme stood out as clearly as the technical content: people valued the community. Volunteers were praised for their patience, speakers for making complex topics accessible, and the hands-on format — with GitHub links, live demos, and side-by-side coding — gave participants something concrete to take home.</P><H1 id="toc-hId-286635301">Looking Ahead</H1><P>UI5con Bengaluru 2026 made one thing clear: seven years was too long to wait. The SAP UI5 ecosystem is moving faster than ever, the community is hungry for it, and Devanahalli proved it can host a world-class developer event. Thank you to every speaker, volunteer, and attendee who made this happen. See you at the next one.</P><P class="lia-align-center" style="text-align: center;"><FONT size="2"><EM>"Looking forward for the next iteration of UI5con."<BR /></EM></FONT><FONT size="2"><STRONG>Participant, Volvo</STRONG></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="1111.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379602i89435798297D2E6E/image-size/large?v=v2&px=999" role="button" title="1111.jpg" alt="1111.jpg" /></span></P><P> </P><P> </P>2026-03-03T12:16:36.382000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/how-to-migrate-ui5-projects-to-the-latest-ui5-best-practices/ba-p/14340388How to Migrate UI5 Projects to the Latest UI5 Best Practices2026-03-03T14:24:01.693000+01:00FlorianVogthttps://community.sap.com/t5/user/viewprofilepage/user-id/216201<P><SPAN class=""><SPAN class="">In Sept</SPAN><SPAN class="">ember</SPAN><SPAN class=""><SPAN> </SPAN>2025, the<SPAN> </SPAN></SPAN><SPAN class="">initial</SPAN><SPAN class=""><SPAN> </SPAN>release of<SPAN> </SPAN></SPAN><SPAN class="">UI5</SPAN><SPAN class=""><SPAN> </SPAN>MCP server was published.<SPAN> </SPAN></SPAN><SPAN class="">In<SPAN> </SPAN></SPAN></SPAN><A class="" href="https://community.sap.com/t5/technology-blog-posts-by-sap/give-your-ai-agent-some-tools-introducing-the-ui5-mcp-server/ba-p/14200825" target="_blank">Give Your AI Agent Some Tools: Introducing the UI5 MCP Server</A> by <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/281023">@merlin_beutlberger</a> <SPAN class=""><SPAN class="">you’ll</SPAN><SPAN class=""><SPAN> </SPAN>find a great overview<SPAN> </SPAN></SPAN><SPAN class="">of</SPAN><SPAN class=""><SPAN> </SPAN>the available features and a detailed step-by-st</SPAN><SPAN class="">ep guide. This blog post<SPAN> </SPAN></SPAN><SPAN class="">focus</SPAN><SPAN class="">es on</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">how<SPAN> </SPAN></SPAN><SPAN class="">UI5</SPAN><SPAN class=""><SPAN> </SPAN>MCP server can support you<SPAN> </SPAN></SPAN><SPAN class="">in</SPAN><SPAN class=""><SPAN> </SPAN>migrating your UI5 project easily to the latest best practices with the help of</SPAN><SPAN class=""><SPAN> </SPAN>GitHub Copilot Coding Agent.<SPAN> </SPAN></SPAN><SPAN class="">T</SPAN><SPAN class="">he results are really good</SPAN><SPAN class="">.</SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_0-1772544160728.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379241iE6BDFEF34865F747/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_0-1772544160728.png" alt="FlorianVogt_0-1772544160728.png" /></span></P><H2 id="toc-hId-1791310823"><SPAN>Prerequisites</SPAN><SPAN>:</SPAN><SPAN> </SPAN></H2><UL><LI><SPAN>The repository that you'd like to migrate must be hosted on GitHub.</SPAN><SPAN> </SPAN></LI><LI><SPAN>Subscribe to a </SPAN><A href="https://github.com/features/copilot/plans" target="_blank" rel="noopener nofollow noreferrer"><SPAN>GitHub Copilot Pro</SPAN></A><SPAN> license to use the GitHub Coding Agent feature. </SPAN></LI></UL><H2 id="toc-hId-1594797318"><SPAN>Initial Setup</SPAN><SPAN> </SPAN></H2><P><SPAN>To use UI5 MCP server in GitHub Copilot Coding Agent, adjust the Coding Agent settings in your repository. Open your repository settings, select the Copilot item, and then select the Coding Agent. </SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_0-1772529255104.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379083i41EC7B9EC1E89D61/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_0-1772529255104.png" alt="FlorianVogt_0-1772529255104.png" /></span></P><P><SPAN class=""><SPAN class="">On the right side,<SPAN> </SPAN></SPAN><SPAN class="">there</SPAN><SPAN class="">'</SPAN><SPAN class="">s</SPAN><SPAN class=""><SPAN> </SPAN>an empty input area where<SPAN> </SPAN></SPAN><SPAN class="">you</SPAN><SPAN class=""><SPAN> </SPAN>enter<SPAN> </SPAN></SPAN><SPAN class="">your</SPAN><SPAN class=""><SPAN> </SPAN>MCP configuration.<SPAN> </SPAN></SPAN><SPAN class="">U</SPAN><SPAN class="">se a similar configuration<SPAN> </SPAN></SPAN><SPAN class="">to the one you</SPAN><SPAN class=""><SPAN> </SPAN>already use in<SPAN> </SPAN></SPAN><SPAN class="">your</SPAN><SPAN class=""><SPAN> </SPAN>local<SPAN> </SPAN></SPAN><SPAN class="">VSCode</SPAN><SPAN class=""><SPAN> </SPAN>settings.</SPAN></SPAN><SPAN class=""> </SPAN></P><pre class="lia-code-sample language-json"><code>{
"mcpServers": {
"ui5-mcp-server": {
"type": "stdio",
"command": "npx",
"tools": [
"run_ui5_linter",
"get_guidelines",
"get_project_info",
"get_version_info",
"get_api_reference",
"get_typescript_conversion_guidelines"
],
"args": [
"@ui5/mcp-server"
]
}
}
}</code></pre><P><SPAN class=""><SPAN class="">Important</SPAN><SPAN class="">:</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">Don’</SPAN><SPAN class="">t</SPAN><SPAN class=""><SPAN> </SPAN>forget to press</SPAN><SPAN class=""><SPAN> </SPAN>the<SPAN> </SPAN></SPAN></SPAN><STRONG><SPAN class=""><SPAN class="">Save MCP configuration</SPAN></SPAN></STRONG><SPAN class=""><SPAN class=""><SPAN> </SPAN>button</SPAN><SPAN class="">.</SPAN></SPAN><SPAN class=""> </SPAN></P><H2 id="toc-hId-1398283813"><SPAN class=""><SPAN class=""><SPAN class="">Let’s</SPAN><SPAN class=""><SPAN> </SPAN>start</SPAN></SPAN><SPAN class=""> </SPAN></SPAN></H2><P><SPAN class=""><SPAN class="">Now</SPAN><SPAN class=""><SPAN> </SPAN>your</SPAN><SPAN class=""><SPAN> </SPAN>repository is ready</SPAN><SPAN class="">.</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">C</SPAN><SPAN class="">reate</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">a</SPAN><SPAN class=""><SPAN> </SPAN>new issue on<SPAN> </SPAN></SPAN><SPAN class="">your</SPAN><SPAN class=""><SPAN> </SPAN>GitHub repository (see</SPAN><SPAN class=""><SPAN> </SPAN></SPAN></SPAN><A class="" href="https://github.com/flovogt/openui5-sample-app/issues/165" target="_blank" rel="noreferrer noopener nofollow"><SPAN class=""><SPAN class="">flovogt/openui5-sample-app #165</SPAN></SPAN></A><SPAN class=""><SPAN class="">) with the title "Migrate to<SPAN> </SPAN></SPAN><SPAN class="">latest</SPAN><SPAN class=""><SPAN> </SPAN>best practices"</SPAN><SPAN class="">.</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">You</SPAN><SPAN class=""><SPAN> </SPAN>could also be more<SPAN> </SPAN></SPAN><SPAN class="">specific</SPAN><SPAN class=""><SPAN> </SPAN>by writing "Migrate to latest UI5</SPAN><SPAN class=""><SPAN> </SPAN>best practices</SPAN><SPAN class="">"</SPAN><SPAN class="">,</SPAN><SPAN class=""><SPAN> </SPAN>but<SPAN> </SPAN></SPAN><SPAN class="">if</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">you want to</SPAN><SPAN class=""><SPAN> </SPAN>modernize the whole project,<SPAN> </SPAN></SPAN><SPAN class="">cho</SPAN><SPAN class="">o</SPAN><SPAN class="">se the more general variant.</SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_1-1772529420213.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379086i0C9776784FEDAE73/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_1-1772529420213.png" alt="FlorianVogt_1-1772529420213.png" /></span></P><P><SPAN class=""><SPAN class="">After the issue is created,<SPAN> </SPAN></SPAN><SPAN class="">assign the GitHub<SPAN> </SPAN></SPAN></SPAN><SPAN class=""><SPAN class=""><STRONG>Copilot</STRONG><SPAN> </SPAN></SPAN></SPAN><SPAN class=""><SPAN class="">user to the issue. Immediately, the Copilot user starts to<SPAN> </SPAN></SPAN><SPAN class="">analyze</SPAN><SPAN class=""><SPAN> </SPAN>the issue</SPAN><SPAN class=""><SPAN> </SPAN>and creates a draft PR</SPAN><SPAN class=""><SPAN> </SPAN></SPAN></SPAN><A class="" href="https://github.com/flovogt/openui5-sample-app/pull/166/" target="_blank" rel="noreferrer noopener nofollow"><SPAN class=""><SPAN class="">flovogt/openui5-sample-app #166</SPAN></SPAN></A><SPAN class=""><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">to resolve the issue.</SPAN></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_2-1772529452552.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379087i61870E23E75903D9/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_2-1772529452552.png" alt="FlorianVogt_2-1772529452552.png" /></span></P><P><SPAN class=""><SPAN class="">In the<SPAN> </SPAN></SPAN><SPAN class="">beginning</SPAN><SPAN class="">,</SPAN><SPAN class=""><SPAN> </SPAN>the PR description<SPAN> </SPAN></SPAN><SPAN class="">contains</SPAN><SPAN class=""><SPAN> </SPAN>just a short recap of the issue to be fixed by this PR. However, in the<SPAN> </SPAN></SPAN><SPAN class="">backgro</SPAN><SPAN class="">u</SPAN><SPAN class="">nd</SPAN><SPAN class="">,</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">the<SPAN> </SPAN></SPAN><SPAN class="">Copilot</SPAN><SPAN class=""><SPAN> </SPAN>Coding Agent</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">start</SPAN><SPAN class="">s</SPAN><SPAN class=""><SPAN> </SPAN>to<SPAN> </SPAN></SPAN><SPAN class="">create<SPAN> </SPAN></SPAN><SPAN class="">a<SPAN> </SPAN></SPAN><SPAN class="">plan</SPAN><SPAN class=""><SPAN> </SPAN>to solve the issue</SPAN><SPAN class="">. After<SPAN> </SPAN></SPAN><SPAN class="">a few</SPAN><SPAN class=""><SPAN> </SPAN>more minutes (</SPAN><SPAN class="">approximately two</SPAN><SPAN class=""><SPAN> </SPAN>minutes</SPAN><SPAN class="">)</SPAN><SPAN class="">, t</SPAN><SPAN class="">he PR description is updated with a detailed<SPAN> </SPAN></SPAN><SPAN class="">plan</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">of<SPAN> </SPAN></SPAN><SPAN class="">what the Coding Agent<SPAN> </SPAN></SPAN><SPAN class="">does</SPAN><SPAN class="">.</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">UI5</SPAN><SPAN class=""><SPAN> </SPAN>MCP server<SPAN> </SPAN></SPAN><SPAN class="">plays</SPAN><SPAN class=""><SPAN> </SPAN>a crucial role</SPAN><SPAN class=""><SPAN> </SPAN>here</SPAN><SPAN class="">. It uses UI5 linter and dedicated migrati</SPAN><SPAN class="">on</SPAN><SPAN class=""><SPAN> </SPAN>guides to<SPAN> </SPAN></SPAN><SPAN class="">make<SPAN> </SPAN></SPAN><SPAN class="">your</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">project</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">compliant with the latest best practices.</SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_3-1772529519722.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379088i2A1385C0F5AD09F2/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_3-1772529519722.png" alt="FlorianVogt_3-1772529519722.png" /></span></P><P><SPAN class=""><SPAN class="">After the plan is made, the Coding Agent<SPAN> </SPAN></SPAN><SPAN class="">goes into<SPAN> </SPAN></SPAN><SPAN class="">execut</SPAN><SPAN class="">ion</SPAN><SPAN class="">. It</SPAN><SPAN class=""><SPAN> </SPAN>commits the results to the<SPAN> </SPAN></SPAN><SPAN class="">corresponding<SPAN> </SPAN></SPAN><SPAN class="">branch<SPAN> </SPAN></SPAN><SPAN class="">and<SPAN> </SPAN></SPAN><SPAN class="">marks<SPAN> </SPAN></SPAN><SPAN class="">t</SPAN><SPAN class="">he steps as completed in the PR description.</SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_4-1772529555570.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379089iC9A0A0DC6FFE3AAA/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_4-1772529555570.png" alt="FlorianVogt_4-1772529555570.png" /></span></P><P><SPAN>After the job is done, the Coding Agent executes the tests to verify functional correctness. Having high code coverage is key here. </SPAN><SPAN>Finally, the Coding Agent starts the project, creates a screenshot, and adds it to the PR description, plus summarizing the impact of all the steps. </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_6-1772529610537.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379091i9C0F360D66DF1E48/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_6-1772529610537.png" alt="FlorianVogt_6-1772529610537.png" /></span></P><P><SPAN class=""><SPAN class="">The overall migration took only a few<SPAN> </SPAN></SPAN><SPAN class="">minutes,</SPAN><SPAN class=""><SPAN> </SPAN>and the code quality is really good</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">- a</SPAN><SPAN class="">t</SPAN><SPAN class=""><SPAN> </SPAN>least when<SPAN> </SPAN></SPAN><SPAN class="">I tried it.<SPAN> </SPAN></SPAN><SPAN class="">Don’t</SPAN><SPAN class=""><SPAN> </SPAN>blame me</SPAN><SPAN class=""><SPAN> </SPAN>if you</SPAN><SPAN class=""><SPAN> </SPAN>experience bad code</SPAN><SPAN class=""><SPAN> - </SPAN></SPAN><SPAN class="">w</SPAN><SPAN class="">e</SPAN><SPAN class="">'</SPAN><SPAN class="">re</SPAN><SPAN class=""><SPAN> </SPAN>in the world of AI</SPAN><SPAN class=""><SPAN> </SPAN>after all</SPAN><SPAN class=""><SPAN> </SPAN></SPAN></SPAN><SPAN class=""><SPAN class=""><span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span></SPAN></SPAN><SPAN class=""><SPAN class=""><SPAN> </SPAN>GitHub Copilot Coding Agent and UI5 MCP server<SPAN> </SPAN></SPAN><SPAN class="">work</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">really well</SPAN><SPAN class=""><SPAN> </SPAN>together.</SPAN></SPAN><SPAN class=""> </SPAN></P><P> </P><H2 id="toc-hId-1201770308"><SPAN class=""><SPAN class=""><SPAN class="">JavaScript to TypeScript Migration</SPAN></SPAN><SPAN class=""> </SPAN></SPAN></H2><P><SPAN class=""><SPAN class="">Enough of praising the AI</SPAN><SPAN class="">.</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">Let’s</SPAN><SPAN class=""><SPAN> </SPAN>challenge<SPAN> </SPAN></SPAN><SPAN class="">Copilot</SPAN><SPAN class=""><SPAN> </SPAN>and UI5 MCP server even further.</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">You might have<SPAN> </SPAN></SPAN><SPAN class="">already<SPAN> </SPAN></SPAN><SPAN class="">read<SPAN> </SPAN></SPAN><SPAN class="">the blog</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">post</SPAN><SPAN class=""><SPAN> </SPAN></SPAN></SPAN><A class="" href="https://community.sap.com/t5/technology-blog-posts-by-sap/ui5-mcp-server-s-new-typescript-migration-feature-real-world-experience-and/ba-p/14289451" target="_blank">UI5 MCP Server's New TypeScript Migration Feature - Real-World Experience and Best Practices</A><SPAN class=""><SPAN class=""><SPAN> by <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/189706">@AndreasKunz</a>. </SPAN></SPAN><SPAN class="">In this case,<SPAN> </SPAN></SPAN><SPAN class="">you</SPAN><SPAN class="">'re</SPAN><SPAN class=""><SPAN> </SPAN>already aware that<SPAN> </SPAN></SPAN><SPAN class="">UI5</SPAN><SPAN class=""><SPAN> </SPAN>MCP server supports such a migration feature</SPAN><SPAN class="">. </SPAN><SPAN class="">But the overall experience</SPAN><SPAN class="">,</SPAN><SPAN class=""><SPAN> </SPAN>without checking out any code<SPAN> </SPAN></SPAN><SPAN class="">locally,</SPAN><SPAN class=""><SPAN> </SPAN>is<SPAN> </SPAN></SPAN><SPAN class="">just amazing</SPAN><SPAN class="">. I<SPAN> </SPAN></SPAN><SPAN class="">created another issue <A class="" href="https://github.com/flovogt/openui5-sample-app/issues/167" target="_blank" rel="noreferrer noopener nofollow">flovogt/openui5-sample-app #167</A> to ask GitHub Copilot to migrate the whole legacy project to TypeScript a</SPAN></SPAN><SPAN class=""><SPAN class="">nd let the Coding Agent do the work in PR<SPAN> </SPAN></SPAN></SPAN><A class="" href="https://github.com/flovogt/openui5-sample-app/pull/168/" target="_blank" rel="noreferrer noopener nofollow"><SPAN class=""><SPAN class="">flovogt/openui5-sample-app #168</SPAN></SPAN></A><SPAN class=""><SPAN class="">.<SPAN> </SPAN></SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_7-1772529744376.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379092iA0C35F8A06E81ACE/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_7-1772529744376.png" alt="FlorianVogt_7-1772529744376.png" /></span></P><P><SPAN class=""><SPAN class="">And</SPAN><SPAN class=""><SPAN> </SPAN>t</SPAN><SPAN class="">he<SPAN> </SPAN></SPAN><SPAN class="">result</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">is</SPAN><SPAN class=""><SPAN> </SPAN>a</SPAN><SPAN class="">wesome! The whole legacy project was migrated to TypeScript in less than<SPAN> </SPAN></SPAN><SPAN class="">half</SPAN><SPAN class=""><SPAN> </SPAN>an hour.<SPAN> </SPAN></SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_8-1772529790854.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379093i4AFBE85C80BE804F/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_8-1772529790854.png" alt="FlorianVogt_8-1772529790854.png" /></span></P><H2 id="toc-hId-1005256803"> </H2><H2 id="toc-hId-808743298"><SPAN class=""><SPAN class="">Summary</SPAN></SPAN></H2><P><SPAN><SPAN class=""><SPAN class="">I was really surprised</SPAN><SPAN class=""> by</SPAN><SPAN class=""> how well the overall integration of </SPAN><SPAN class="">UI5</SPAN><SPAN class=""> MCP server works</SPAN><SPAN class="">. The whole job would have taken me at least </SPAN><SPAN class="">one</SPAN><SPAN class=""> day </SPAN><SPAN class="">to do it right</SPAN><SPAN class="">. T</SPAN><SPAN class="">he agent do</SPAN><SPAN class="">es</SPAN><SPAN class=""> most of the </SPAN><SPAN class="">work,</SPAN><SPAN class=""> and I can focus on code review</SPAN><SPAN class=""> and other tasks still to be done by humans. Welcome to the world of AI, UI5!</SPAN></SPAN><SPAN class=""> </SPAN></SPAN></P>2026-03-03T14:24:01.693000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/sap-fiori-elements-new-documentation-structure/ba-p/14344845SAP Fiori Elements: New Documentation Structure2026-03-09T13:58:34.080000+01:00JannaLisahttps://community.sap.com/t5/user/viewprofilepage/user-id/1720234<P><FONT size="4">We're excited to announce a complete restructure of the <A title="Developing Apps with SAP Fiori Elements" href="https://ui5.sap.com/#/topic/03265b0408e2432c9571d6b3feb6b1fd" target="_self" rel="noopener noreferrer">SAP Fiori elements documentation</A>. We now provide separate entry points for OData V4 and OData V2, making it easier to navigate their different feature sets. The new structure reflects our focus on SAP Fiori elements for OData V4 and its building blocks, and it is aligned with the SAP Fiori development portal to ensure a consistent user experience.</FONT></P><P><FONT size="5"><STRONG>Separation of OData V4 and V2 Documentation</STRONG></FONT></P><P>Separated entry points for OData V4 and OData V2 make it easier to find your way around our many features. After choosing the right entry point, you can be sure that all the information you see is relevant to the version you use.</P><P>For OData V4, the revised documentation structure is centered around our building blocks. All related features are now placed together, reducing browsing time and helping you find what you need faster.</P><P>For OData V2, we've kept the documentation structure unchanged to ensure stability for our customers. You'll still find all topics exactly where you expect them. And while our focus going forward is on V4, we continue to support and update the V2 documentation as well.</P><P><FONT size="5"><STRONG>Focus on Building Blocks at the Core</STRONG></FONT></P><P>The new documentation structure organizes topics around <A title="Building Blocks" href="https://ui5.sap.com/#/topic/24c1304739dd4f19af0ce2482c4d9bbe" target="_self" rel="noopener noreferrer">building blocks</A>, which are the foundation of both floorplans and custom pages.</P><P>You may notice that some features can be consumed in different ways depending on your context:</P><UL><LI>When a building block is used within a <A title="Standard Floorplans" href="https://ui5.sap.com/#/topic/797c3239b2a9491fa137e4998fd76aa7" target="_self" rel="noopener noreferrer">standard floorplan</A>, you typically configure its features through annotations or manifest settings.</LI><LI>When the same building block is used on a <A title="Custom Page" href="https://ui5.sap.com/#/topic/02104977ca4c40b68c6a9fc132bbea0d" target="_self" rel="noopener noreferrer">custom page</A>, you control its features through the properties and methods it exposes.</LI></UL><P>Our documentation highlights these differences with clear notes, helping you choose the right approach for your use case.</P><P><FONT size="5"><STRONG>Harmonization Between Documentation & SAP Fiori Development Portal </STRONG></FONT></P><P>The <A href="https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html" target="_blank" rel="noopener noreferrer">SAP Fiori development portal</A> is our one-stop resource designed to help all project team members – from developers to business analysts – explore options, collaborate, and make informed decisions when building SAP Fiori apps. It supports the metadata-driven approach of SAP Fiori elements for OData V4, which offers two flexible paths:</P><UL><LI>Custom layouts using reusable building blocks, or</LI><LI>Standard floorplans for rapid development.</LI></UL><P>Both paths deliver consistent, enterprise-ready applications that follow the SAP Design System guidelines, ensuring harmonized user experience while allowing for configuration when needed.</P><P>You can immediately see the harmonization between the structure of the SAP Fiori development portal and our new documentation structure:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="FE Restructure Blog Post Final.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381519i112303A4C5CDE27F/image-size/large?v=v2&px=999" role="button" title="FE Restructure Blog Post Final.png" alt="FE Restructure Blog Post Final.png" /></span></P><P><FONT size="5"><STRONG>Ongoing Enhancements to Content</STRONG></FONT></P><P>We’re continuously enhancing our documentation – not only with new features, but also by enriching the content with cross-references, linking related topics, and connecting you to relevant resources.</P><P>We also listen to your feedback, so please continue to provide us with ideas about how to further improve our content!</P><P> </P><P> </P><P> </P>2026-03-09T13:58:34.080000+01:00https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-issue-39-march-2026/ba-p/14334703SAP Fiori Development newsletter issue #39 (March 2026)2026-03-10T15:31:16.369000+01:00PeterSpielvogelhttps://community.sap.com/t5/user/viewprofilepage/user-id/543<P>As we get into the rhythm of 2026, it seems that AI is addressing more coding use cases than even a few months ago. This will be on full display at UI5con, where AI topics will likely comprise a higher percentage of the sessions than last year. Learn more about UI5con at <A href="https://openui5.org/ui5con/faq.html" target="_blank" rel="noopener nofollow noreferrer">https://openui5.org/ui5con/faq.html</A>, including how to attend, sponsor, or propose a topic for a session.</P><P>If you want to join other developers to discuss various traditional and AI-powered Fiori development-related topics, I encourage you to join our monthly SAP Fiori development roundtable. <A href="https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.google.com%2Fforms%2Fd%2F1ZqIX3zzGBOOIqehmlIRz_HhpQEhqunkLSzN1gnaOwP8%2Fedit&data=05%7C02%7Cpeter.spielvogel%40sap.com%7C1744854ba1f649092b6b08dd30c5a09e%7C42f7676cf455423c82f6dc2d99791af7%7C0%7C0%7C638720347573866887%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=xgQxtmNy3e97xOOJC304tGHhsgIVLId5KJSRNyshxq0%3D&reserved=0" target="_blank" rel="noopener nofollow noreferrer">Register online</A> or email me for an invitation.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SAP_Fiori_Dev_Newsletter_39.png" style="width: 659px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/378693i582D83CED2F8E4A8/image-size/large?v=v2&px=999" role="button" title="SAP_Fiori_Dev_Newsletter_39.png" alt="SAP_Fiori_Dev_Newsletter_39.png" /></span></P><H2 id="toc-hId-1787739649" id="toc-hId-1790510057">Development News</H2><P><STRONG>Mastering filtering and search capabilities in SAP Fiori elements for OData V4</STRONG></P><P>The filter bar is the primary component for data filtering in SAP Fiori elements applications. It appears at the top of list report page applications and provides users with an intuitive interface to narrow down large datasets. This article discusses search capability, support for the Clear button, custom filters, and of course, how the filter bar can leverage AI capabilities. <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/mastering-filtering-and-search-capabilities-in-sap-fiori-elements-for-odata/ba-p/14307029" target="_blank">Learn more</A>.</P><P><STRONG>Getting past the limitations of using AI for code generation</STRONG></P><P>Dirk Roeckmann shares his perspectives on coding with AI agents based on transformer models. He starts with why he uses AI and then shares some limitations of AI models and how to get around these pitfalls. <A href="https://community.sap.com/t5/technology-blog-posts-by-members/setting-the-right-expectations-around-ai-for-code-generation-and-getting/ba-p/14327300" target="_blank">Read his insights</A>.</P><P><STRONG>UI5 MCP </STRONG><STRONG>server in T</STRONG><STRONG>he Open Source Way podcast</STRONG></P><P>This episode covers the intricacies of the Model Context Protocol (MCP) within the SAP ecosystem, a pivotal component designed to offer domain expertise to LLMs. Join Tim Back and Florian Vogt as we unpack the role and significance of MCP in the SAP ecosystem in the world of AI. (UI5 MCP server <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/give-your-ai-agent-some-tools-introducing-the-ui5-mcp-server/ba-p/14200825" target="_blank">blog post</A>, <A href="https://github.com/UI5/mcp-server" target="_blank" rel="noopener nofollow noreferrer">GitHub</A>)</P><UL><LI>Spotify: <A href="https://open.spotify.com/episode/1Z1GTmFqY5P5Va3T8t33RG?si=mDX84dfwQmi_NrhkXvxtzg" target="_blank" rel="noopener nofollow noreferrer">UI5 & MCP - Navigating the Model Context Protocol in SAP</A></LI><LI>Apple Podcast: <A href="https://podcasts.apple.com/us/podcast/ui5-mcp-navigating-the-model-context-protocol-in-sap/id1535460646?i=1000749280589" target="_blank" rel="noopener nofollow noreferrer">UI5 & MCP - Navigating the Model Context Protocol in SAP</A></LI></UL><P><STRONG>UI5 MCP </STRONG><STRONG>server </STRONG><STRONG>extended for UI Integration Cards </STRONG><STRONG>generation</STRONG></P><P>The UI5 MCP Server now supports the development of UI Integration Cards. It includes three new tools to assist Large Language Models (LLMs) in creating new cards from scratch or editing existing ones, following the best practices for card development. <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/ui5-mcp-server-got-extended-for-ui-integration-cards-generation/ba-p/14312670" target="_blank">See details</A>.</P><P><STRONG>Configure Your SAP Fiori Elements Apps: Introducing Fine-Tuning in the SAP Fiori Development Portal</STRONG></P><P>Annotations in SAP Fiori elements applications define what data to display, how to structure it, and which features to enable. However, not every UI behavior can or should be controlled through annotations. Some aspects require configuration settings that fine-tune how building blocks render and behave. <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/configure-your-sap-fiori-elements-apps-introducing-fine-tuning-in-the-sap/ba-p/14335492" target="_blank">Learn more</A>.</P><P><STRONG>New geomap </STRONG><STRONG>control </STRONG><STRONG>for your SAPUI5 app</STRONG></P><P>A new control in the MDC library has been released. It is displaying interactive maps — visualizing GeoJSON data, integrating vector and raster tiles from various providers, enabling features like clustering and selection, or handling user interaction — sap.ui.mdc.Geomap offers a native UI5 interface to Geomaps. <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/the-new-geomap-control-in-mdc-library-bring-sap-geomap-into-your-ui5-apps/ba-p/14325044" target="_blank">See details</A>.</P><H2 id="toc-hId-1591226144" id="toc-hId-1593996552">Events</H2><P><STRONG>SAP UX Innovation Day </STRONG></P><P>We are planning more SAP UX Innovation Days in 2026. This name replaces the SAP Fiori Innovation Day brand we used in 2024 and 2025. Watch your inbox for announcements about where and when we will be hosting these events. Most will occur in the fall, both before and after SAP TechEd.</P><P><STRONG>New Customer Engagement Initiative (CEI project): "Customize SAPUI5 apps for business users"</STRONG> Provide feedback on new and planned features in SAPUI5 flexibility - Key user adaptation: <A href="https://influence.sap.com/sap/ino/#campaign/4163" target="_self" rel="noopener noreferrer">Register here</A>.</P><H2 id="toc-hId-1311650375" id="toc-hId-1397483047"><STRONG>Back issues from the past year</STRONG></H2><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-january-2026-issue-38/ba-p/14304753" target="_blank">SAP Fiori development newsletter January 2026 (issue #38)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-november-2025-issue-37/ba-p/14268465" target="_blank">SAP Fiori development newsletter November 2025 (issue #37)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-september2025-issue-36/ba-p/14212556" target="_blank">SAP Fiori development newsletter September 2025 (issue #36)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-july-2025-issue-35/ba-p/14139032" target="_blank">SAP Fiori development newsletter July 2025 (issue #35)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-may-2025-issue-34/ba-p/14091410" target="_blank">SAP FIori development newsletter May 2025 (Issue #34)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-march-2025-issue-33/ba-p/14036207" target="_blank">SAP Fiori development newsletter March 2025 (Issue #33)</A></P><P> </P>2026-03-10T15:31:16.369000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/key-user-adaptation-powerful-new-features-amp-seamless-transition-to/ba-p/14350093Key User Adaptation: Powerful New Features & Seamless Transition to Developer Extensibility2026-03-17T08:11:34.257000+01:00MK069https://community.sap.com/t5/user/viewprofilepage/user-id/1535402<P>With key user adaptation, you can change the user interface of SAP Fiori apps directly in the Fiori launchpad — intuitively and without having to write new code. The changes are upgrade-safe adaptations to SAP Fiori apps. Key users can open the UI Adaptation mode for a Fiori app directly from their user menu in the Fiori launchpad (menu entry <STRONG>Adapt UI</STRONG>).</P><P>A key user is a business expert who is authorized to make changes on behalf of other users — for example a team member who is interested in technology. The goal of key user extensibility is to empower business users to be able to adapt their working environment to suit their needs, without having to rely on system administrators.</P><H3 id="toc-hId-1921314206"> </H3><H3 id="toc-hId-1724800701"><STRONG>What can key users change with key user adaptation?</STRONG></H3><P>Key users can perform the following changes in Fiori apps based on SAP Fiori <SPAN>elements</SPAN>:</P><UL><LI>Hide/show the information that shall be visible in the object page header</LI><LI>Hide/show tabs, sections, tables, or action buttons on the object page</LI><LI>Define the fields visible in forms on the object page</LI><LI><STRONG><SPAN>Set the configuration </SPAN></STRONG><STRONG>for tables</STRONG> (select all, selection mode, thresholds, view settings, export, etc.)</LI><LI><STRONG><SPAN>Set the configuration</SPAN></STRONG><STRONG> for the filter bar</STRONG> (clear button, usage of the semantic date range control)</LI><LI><STRONG><SPAN>Set the configuration</SPAN></STRONG><STRONG> for the complete list report / object page</STRONG> (variant management, initial load)</LI><LI><STRONG>Change Text Arrangement</STRONG> (ID only, Text first, Text last, Text only)</LI><LI><STRONG>Change Labels</STRONG> (global label changes)</LI><LI>Rename (only for a dedicated field – applies only locally to a form field)</LI><LI>Define the fields visible in the mass edit dialog. In the key user adaptation mode, all fields except static read-only fields are available.</LI><LI>And more</LI></UL><P>The scope was continuously enhanced. The <STRONG>bold items</STRONG> above are extremely powerful new features available since <STRONG>S/4HANA </STRONG><STRONG><SPAN>Cloud Public Edition</SPAN></STRONG><STRONG> 2508 / S/4HANA <SPAN>Cloud </SPAN></STRONG><STRONG>Private <SPAN>Edition </SPAN></STRONG><STRONG>2025 / On-Premise 2025</STRONG>. They are described in detail in the following sections.</P><P><SPAN> </SPAN></P><H3 id="toc-hId-1528287196"><STRONG>New feature: configuration for tables</STRONG></H3><P>The <STRONG>Configuration</STRONG> functionality is available in key user adaptation mode when the context menu entry <STRONG>Configuration</STRONG> is selected on a table, on the filter bar, or on page level. The context menu on a table contains — for example in Fiori <SPAN>elements</SPAN> V4 — the following entries:</P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_ChangeTableConfiguration1.png" style="width: 210px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384230i47FD4FC134BBD405/image-size/large?v=v2&px=999" role="button" title="ADP_ChangeTableConfiguration1.png" alt="ADP_ChangeTableConfiguration1.png" /></span> </SPAN></P><P>Among other things, the following settings can be configured here:</P><UL><LI><STRONG>Enable Table Export</STRONG> — configures whether the Export button is displayed in the table.</LI><LI><STRONG>Frozen Column Count</STRONG> — configures the count of columns that are always visible when scrolling horizontally.</LI><LI><STRONG>Personalization</STRONG> — configures whether the table personalization settings are enabled. To configure the listed settings individually, choose <STRONG>Own Settings</STRONG>.</LI><LI><STRONG>Row Count</STRONG> — configures the number of rows to be displayed in the table.</LI><LI><STRONG>Width Including Column Header</STRONG> — configures whether the column header label is considered when calculating the column width.</LI><LI><STRONG>Enable Select All</STRONG> — configures whether the <STRONG>Select All</STRONG> option is displayed in the table.</LI><LI><STRONG>Selection Limit</STRONG> — configures the maximum limit of the number of rows that can be selected at once (e.g., by using <STRONG>Select All</STRONG>).</LI><LI><STRONG>Threshold</STRONG> — determines the maximum number of entries loaded when the application is started. <STRONG>Scroll Threshold</STRONG> determines the maximum number loaded during scrolling if new entries need to be fetched. Increasing these settings will lead to an increased initial load time but <SPAN>deliver</SPAN> a smoother scroll experience.</LI></UL><P><STRONG>Note:</STRONG> Not all settings listed above are available for all table types and page types. Furthermore, there are differences between Fiori <SPAN>elements</SPAN> V2 and Fiori <SPAN>elements</SPAN> V4 (Fiori <SPAN>elements</SPAN> V2 offers fewer settings).</P><P><STRONG>Example – List Report Grid Table in Fiori <SPAN>elements</SPAN></STRONG><STRONG> V4:</STRONG></P><P><SPAN> <span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_ChangeTableConfiguration2.png" style="width: 660px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384231i398C6B2CD3D3FD02/image-size/large?v=v2&px=999" role="button" title="ADP_ChangeTableConfiguration2.png" alt="ADP_ChangeTableConfiguration2.png" /></span></SPAN></P><H3 id="toc-hId-1331773691"> </H3><H3 id="toc-hId-1135260186"><STRONG>New feature: configuration for the filter bar</STRONG></H3><P>The <STRONG>Configuration</STRONG> context menu entry on the filter bar opens settings for the filter bar. Among other things, the following settings can be configured here:</P><UL><LI><STRONG>Display Clear Button</STRONG> — configures whether the Clear button is displayed in the filter bar.</LI><LI><STRONG>Enable Semantic Date Range menu options</STRONG> — configures that single date range filters offer semantic operators (like "Today", "This Month", "Last Year").</LI></UL><P><STRONG>Example – List Report Filter Bar in Fiori <SPAN>elements</SPAN></STRONG><STRONG> V4:</STRONG></P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_ChangeFilterBarConfiguration.png" style="width: 561px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384232iCAEBF1ACBA105EED/image-size/large?v=v2&px=999" role="button" title="ADP_ChangeFilterBarConfiguration.png" alt="ADP_ChangeFilterBarConfiguration.png" /></span> </SPAN><SPAN> </SPAN></P><H3 id="toc-hId-938746681"> </H3><H3 id="toc-hId-742233176"><STRONG>New feature: configuration for the complete list report / object page</STRONG></H3><P>The <STRONG>Configuration</STRONG> context menu entry at page level opens settings for the entire List Report or Object Page. Among other things, the following settings can be configured here:</P><UL><LI><STRONG>Variant Management</STRONG> (<STRONG>Table Variant Management</STRONG>) — configures how variant management is used on the List Report page or in tables on the Object Page.</LI><LI><STRONG>Initial Load</STRONG> — configures how data is loaded initially when the app is opened.</LI></UL><P><STRONG>Example – List Report in Fiori <SPAN>elements</SPAN></STRONG><STRONG> V4:</STRONG></P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_ChangePageConfiguration.png" style="width: 560px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384233iE9AFAF89D1773E75/image-size/large?v=v2&px=999" role="button" title="ADP_ChangePageConfiguration.png" alt="ADP_ChangePageConfiguration.png" /></span> </SPAN></P><H3 id="toc-hId-545719671"> </H3><H3 id="toc-hId-349206166"><STRONG>New feature: change text arrangement</STRONG></H3><P>The <STRONG>Change Text Arrangement</STRONG> functionality is available in key user adaptation mode when the context menu entry <STRONG>Change Text Arrangement</STRONG> is selected on a table, on the filter bar, or on a form.</P><P>This powerful new functionality allows changing centrally the text arrangement for all relevant fields in a Fiori app. A key user can decide for each field whether it shall be shown as:</P><TABLE><TBODY><TR><TD><P><STRONG>Option</STRONG></P></TD><TD><P><STRONG>Example (Company Code "0001" / "SAP AG")</STRONG></P></TD></TR><TR><TD><P>ID only</P></TD><TD><P>0001</P></TD></TR><TR><TD><P>Text only</P></TD><TD><P>SAP AG</P></TD></TR><TR><TD><P>Text first</P></TD><TD><P>SAP AG (0001)</P></TD></TR><TR><TD><P>Text last</P></TD><TD><P>0001 (SAP AG)</P></TD></TR></TBODY></TABLE><P><STRONG>Note:</STRONG> These changes are independent of specific controls. You change the text arrangement for the underlying OData property. If a specific field or control does not use the text arrangement from the OData property, the changes will not be applied to that control.</P><P><SPAN> <span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_ChangeTextArrangement.png" style="width: 812px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384234i68A2608CDF7E4FEA/image-size/large?v=v2&px=999" role="button" title="ADP_ChangeTextArrangement.png" alt="ADP_ChangeTextArrangement.png" /></span></SPAN></P><H3 id="toc-hId-152692661"> </H3><H3 id="toc-hId--119052213"><STRONG>New feature: change labels</STRONG></H3><P>The <STRONG>Change Labels</STRONG> functionality is available in key user adaptation mode when the context menu entry <STRONG>Change Labels</STRONG> is selected on a table, on the filter bar, or on a form.</P><P>This allows changing the labels <SPAN>centrally</SPAN> for all relevant fields in a Fiori app: if an identical label is available in the filter bar, in tables, forms, and charts of a Fiori application, then all places are changed consistently. This is the key difference from the existing <STRONG>Rename</STRONG> feature, which only applies locally to a form field.</P><P><STRONG>Example:</STRONG> You can consistently change the text "Material" to "Product" across your entire Fiori app.</P><P><STRONG>Note:</STRONG> These changes are independent of specific controls. You change the label for the underlying OData property. If a specific field or control does not use the text from the OData property, the changes will not be applied to that control.</P><P><SPAN> <span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_ChangeLabels.png" style="width: 810px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384235iB1187B4FF23EF848/image-size/large?v=v2&px=999" role="button" title="ADP_ChangeLabels.png" alt="ADP_ChangeLabels.png" /></span></SPAN></P><H3 id="toc-hId--315565718"> </H3><H3 id="toc-hId--512079223"><STRONG>Need more complex changes? Seamless Transition from Key User to Developer Extensibility.</STRONG></H3><P>If you need to make more complex changes — for example, adding fragments to visualize data as a chart, changing a responsive table to a grid table, or making the app available to different business roles, user groups, organizational units, and countries — you can extend an application by creating an <STRONG>SAPUI5 Adaptation Project</STRONG> (developer adaptation).</P><P>When creating an SAPUI5 Adaptation Project, you can select the brand-new option <STRONG>Import Key User Changes</STRONG> (available since S/4HANA <SPAN>Cloud Public Edition</SPAN> 2602; not yet available for S/4HANA Private Cloud / On-Premise) to import all key user changes made so far. This means key user changes will not be lost — they become part of the new SAPUI5 Adaptation Project.</P><P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ADP_KeyUserChanges.png" style="width: 989px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384236iF3D4C02E44D45024/image-size/large?v=v2&px=999" role="button" title="ADP_KeyUserChanges.png" alt="ADP_KeyUserChanges.png" /></span> </SPAN></P><P>For an introduction to Adaptation Projects, see <SPAN><A href="https://developers.sap.com/group.sapui5-adaptation-projects.html" target="_blank" rel="noopener noreferrer">Work with SAPUI5 Adaptation Projects to Make Changes and Extend the Source Code of an Application Variant of an SAP Fiori Application in SAP S/4HANA Cloud Public Edition</A></SPAN>.</P><P>For more detailed information, see <SPAN><A href="https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/extending-sap-fiori-application" target="_blank" rel="noopener noreferrer">Extending SAP Fiori Applications</A></SPAN>.</P><H3 id="toc-hId--708592728"> </H3><H3 id="toc-hId--905106233"><STRONG>Prerequisites</STRONG></H3><P><STRONG>Public Cloud:</STRONG></P><UL><LI>The IAM app <SPAN>F5933_LRST_TRAN</SPAN> provides the relevant authorizations. It is included in the business catalog <SPAN>SAP_CORE_BC_EXT_FLX_CUS_PC</SPAN> (see <SPAN><A href="https://help.sap.com/docs/SAP_S4HANA_CLOUD/4fc8d03390c342da8a60f8ee387bca1a/5c424437bf794f809087fdce391149f2.html" target="_blank" rel="noopener noreferrer">Adapting SAP Fiori UIs at Runtime - Key User Adaptation</A></SPAN>).</LI></UL><P><STRONG>Private Cloud / On-Premise:</STRONG></P><UL><LI>Your administrator assigned you to the authorization role SAP_UI_FLEX_KEY_USER (see <SPAN><A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/a7b390faab1140c087b8926571e942b7/402b392585834dd38dd381d8f04b2616.html" target="_blank" rel="noopener noreferrer">Enabling Key User Adaptation</A></SPAN>).</LI></UL><P><STRONG>General requirements:</STRONG></P><UL><LI>You run your SAPUI5 app on a desktop computer or laptop.</LI><LI>Your app is enabled for key user adaptation.</LI><LI>A minimum screen size of 800×600 is required for key user adaptation. Anything smaller can affect the toolbar elements, causing them to overlap.</LI></UL><P><SPAN> </SPAN></P><H3 id="toc-hId--1101619738"><STRONG>Tips for Key User Adaptation for Fiori Apps in SAP S/4HANA</STRONG></H3><P><STRONG>Where do I make Key User changes?</STRONG></P><UL><LI>Key users typically make changes in the Development environment.</LI></UL><P><STRONG>How do I transport Key User changes?</STRONG></P><UL><LI>Active changes must be published to make them ready for transport.</LI><LI>To publish your changes for transport, you must be assigned a transport request by your technical team.</LI><LI>Your technical team manages the transports through to your Production environment.</LI></UL><P><SPAN> </SPAN></P><H3 id="toc-hId--1298133243"><STRONG>Key takeaways</STRONG></H3><UL><LI><STRONG>Key User Adaptation</STRONG> lets you make common changes to SAP Fiori apps directly in the Fiori Launchpad — no developer knowledge required.</LI><LI>Key User Adaptation is now extremely powerful with new options for:</LI><UL><LI>Configuring important UI elements (tables, filter bar, complete list report / object page)</LI><LI>Changing the text arrangement of fields</LI><LI>Changing labels globally across an entire Fiori app</LI></UL><LI>Changes are made in the <STRONG>Development environment</STRONG> and published for transport.</LI><LI>Published changes can be transported to other environments by your technical team.</LI><LI>Key User Adaptation changes can be <STRONG>imported</STRONG> when creating an SAPUI5 Adaptation Project for more complex changes (S/4HANA Public Cloud 2602+). This allows a seamless transition from key user to developer extensibility.</LI></UL><H3 id="toc-hId--1494646748"> </H3><H3 id="toc-hId--1691160253"><STRONG>Where can I learn more about Key User Adaptation for Fiori Apps in SAP S/4HANA?</STRONG></H3><UL><LI><SPAN><A href="https://help.sap.com/docs/SAP_S4HANA_CLOUD/4fc8d03390c342da8a60f8ee387bca1a/5c424437bf794f809087fdce391149f2.html" target="_blank" rel="noopener noreferrer">SAP Help – Key User Adaptation (S/4HANA Cloud Public Edition)</A></SPAN>: Adapting SAP Fiori UIs at Runtime – Key User Adaptation</LI><LI><SPAN><A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/a7b390faab1140c087b8926571e942b7/5c424437bf794f809087fdce391149f2.html" target="_blank" rel="noopener noreferrer">SAP Help – Key User Adaptation (S/4HANA Cloud Private Edition and On-Premise)</A></SPAN>: Adapting SAP Fiori UIs at Runtime – Key User Adaptation</LI><LI><SPAN><A href="https://developers.sap.com/mission.sapui5-key-user-adaptation.html" target="_blank" rel="noopener noreferrer">SAP Learning – Tutorials: Key User Adaptation for SAPUI5 Applications</A></SPAN></LI><LI><SPAN><A href="https://sapui5untested.int.sap.eu2.hana.ondemand.com/#/topic/59bfd317ed5d4af3b490abbe7a9731d8" target="_blank" rel="noopener nofollow noreferrer">SAP Help – SAP Fiori elements V4: Extending Delivered Apps With Key User Adaptation</A></SPAN></LI><LI><SPAN><A href="https://sapui5untested.int.sap.eu2.hana.ondemand.com/#/topic/7837c7a3d1494731aff54e9a95230cea" target="_blank" rel="noopener nofollow noreferrer">SAP Help – SAP Fiori elements V2: Adapting the UI</A></SPAN></LI></UL>2026-03-17T08:11:34.257000+01:00https://community.sap.com/t5/frontend-ui5-sap-fiori-blog-posts/building-a-scalable-micro-frontend-dashboard-with-sapui5-integration-cards/ba-p/14350435Building a Scalable Micro-Frontend Dashboard with SAPUI5 Integration Cards2026-03-17T10:56:08.588000+01:00nguyen_nguyen881https://community.sap.com/t5/user/viewprofilepage/user-id/2262793<H1 id="toc-hId-1663152428"><SPAN>Introduction</SPAN></H1><P class="">Building an enterprise-grade analytics dashboard is challenging. When you add requirements like multi-team development, independent deployment cycles, and the need for extensibility, traditional monolithic approaches quickly become unmanageable.</P><P class="">This article shares our proposal building the<SPAN> Performance Dashboard<SPAN> at SAP—a micro-frontend architecture that supports dozens of independent KPI widgets, dynamic filtering, cross-widget interactions, and continuous deployment—all while maintaining team autonomy and code quality.</SPAN></SPAN></P><P class="">This article shares practical patterns for building a micro-frontend dashboard architecture that supports:</P><UL><LI>Dozens of independent KPI widgets</LI><LI>Dynamic filtering across all widgets</LI><LI>Cross-widget interactions</LI><LI>Continuous deployment with team autonomy</LI></UL><P>Whether you're building analytics dashboards, composable UIs, or exploring micro-frontend patterns, this deep-dive offers practical insights backed by real-world architectural decisions.</P><H1 id="toc-hId-1466638923">The Challenge: Complex Dashboard, Multiple Teams</H1><P><SPAN>An enterprise analytics dashboard that provides managers with real-time visibility into business metrics across multiple dimensions:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="nguyen_nguyen881_0-1773762489929.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384909i495914531127FF00/image-size/large?v=v2&px=999" role="button" title="nguyen_nguyen881_0-1773762489929.png" alt="nguyen_nguyen881_0-1773762489929.png" /></span></P><P class=""><STRONG>Requirements:</STRONG></P><UL class=""><LI>40+ KPI widgets across multiple views × multiple dimensions</LI><LI>Multiple teams developing widgets independently</LI><LI>Continuous deployment without blocking other teams</LI><LI>Dynamic filters affecting all widgets simultaneously</LI><LI>Cross-filtering when users click chart segments</LI><LI>Grid customization (drag-drop, resize, hide/show)</LI></UL><P class=""><STRONG>Why Traditional Approaches Fail:</STRONG></P><UL class=""><LI>Monolithic SPA: Every widget change requires full redeployment</LI><LI>Tight coupling: One broken widget blocks entire dashboard</LI><LI>Single pipeline:<SPAN> Multiple teams competing for deployment window</SPAN></LI></UL><P><STRONG>We needed true micro-frontend architecture.</STRONG></P><H2 id="toc-hId-1399208137"> </H2><H1 id="toc-hId-1073611913">Architecture Decision 1: Repository Structure</H1><H3 id="toc-hId-1135263846">The Question</H3><P class="">Should the dashboard shell and KPI widgets live in one repository or separate repositories?</P><H3 id="toc-hId-938750341">Option A: Monorepo</H3><PRE><CODE>analytics-dashboard/ ← Single repo
├── dashboard-shell/
│ ├── webapp/
│ └── ui5.yaml
└── widgets/
├── widget-a/
├── widget-b/
└── ...</CODE></PRE><P><STRONG>Pros:<SPAN> Simple setup, single CI/CD pipeline<BR /><STRONG>Cons:<SPAN> Deployment coupling, merge conflicts, repository grows massive</SPAN></STRONG></SPAN></STRONG></P><H3 id="toc-hId-742236836"> </H3><H3 id="toc-hId-545723331">Option B: Two Repositories - Selected</H3><PRE><CODE>dashboard-shell/ ← Repo 1: Orchestration layer
├── webapp/
│ ├── config/layout.json
│ ├── controller/Dashboard.controller.ts
│ ├── model/LayoutManager.ts
│ └── view/Dashboard.view.xml
widget-registry/ ← Repo 2: All widgets
├── widgets/
│ ├── widget-a/
│ ├── widget-b/
│ └── ...
├── registry-service/
│ └── widget-registry.json
└── build.sh</CODE></PRE><P class=""><STRONG>Contract Between Repositories: Repository Exposes Consumes</STRONG></P><TABLE border="1" width="100%"><TBODY><TR><TD width="50%">Repository</TD><TD width="25%">Exposes</TD><TD width="25%">Consumes</TD></TR><TR><TD width="50%">widget-registry</TD><TD width="25%"><P><SPAN>GET /api/widget-registry</SPAN></P><P><SPAN>GET /[widgetName]/*</SPAN></P></TD><TD width="25%">-</TD></TR><TR><TD width="50%">dashboard-shell</TD><TD width="25%"><P><SPAN>-</SPAN></P></TD><TD width="25%"><P><SPAN>Discovers widgets</SPAN></P><P><SPAN>Loads assets dynamically</SPAN></P></TD></TR></TBODY></TABLE><P><STRONG>Why We Chose Two Repositories:</STRONG></P><P><STRONG>Independent deployment cycles:</STRONG></P><UL class=""><LI>Dashboard updates don't require widget releases</LI><LI>Widget teams deploy on their own schedule</LI><LI>Broken widget doesn't block dashboard</LI></UL><P><STRONG>Clear ownership boundaries</STRONG></P><UL class=""><LI>Dashboard team owns orchestration</LI><LI>Widget teams own visualizations</LI><LI>Contract enforces decoupling</LI></UL><P><STRONG>Scalable CI/CD</STRONG></P><UL class=""><LI>Two focused pipelines vs one massive pipeline</LI><LI>Faster builds (only changed repo rebuilds)</LI><LI>Parallel development without conflicts</LI></UL><P><STRONG>Trade-off:<SPAN> Slightly more complex integration testing, but worth it for deployment flexibility.</SPAN></STRONG></P><H2 id="toc-hId-220127107"> </H2><H1 id="toc-hId--105469117">Architecture Decision 2: Integration Strategy</H1><P><STRONG>The Question</STRONG></P><P><SPAN>How should the dashboard load and render independent widgets at runtime?</SPAN></P><H3 id="toc-hId--119048553">Evaluated Options</H3><H4 id="toc-hId--608965065">Option A: Iframe-Based<SPAN> </SPAN></H4><pre class="lia-code-sample language-markup"><code><iframe src="https://widgets.example.com/widget-a"></iframe></code></pre><P><STRONG>Pros:</STRONG>Complete isolation<STRONG><SPAN><BR />Cons: </SPAN></STRONG>Performance overhead, difficult communication, styling inconsistency, accessibility issues</P><P> </P><H4 id="toc-hId--805478570">Option B: Native Web Components</H4><pre class="lia-code-sample language-javascript"><code>customElements.define('analytics-widget', class extends HTMLElement {});</code></pre><P><STRONG>Pros: </STRONG>Browser-native, framework-agnostic<STRONG><SPAN><BR />Cons: </SPAN></STRONG>No SAPUI5 features, reinvent data binding/routing/i18n, steep learning curve</P><P> </P><H4 id="toc-hId--1001992075">Option C: UI5 Components</H4><pre class="lia-code-sample language-javascript"><code>import Component from "sap/ui/core/Component";
const oComponent = await Component.create({ name: "com.example.widget" });</code></pre><P><STRONG>Pros: </STRONG>Full SAPUI5 capabilities<STRONG><SPAN><BR />Cons: </SPAN></STRONG>Complex lifecycle management, no standard metadata format</P><P> </P><H4 id="toc-hId--1198505580">Option D : UI5 Integration Cards - Selected</H4><P><STRONG>Manifest-based configuration:</STRONG></P><pre class="lia-code-sample language-json"><code>{
"sap.app": {
"id": "com.example.ordervalue",
"type": "card"
},
"sap.card": {
"type": "Component",
"header": {
"title": "Order Value at Risk"
},
"content": {
"componentName": "com.example.ordervalue"
}
}
}</code></pre><P><STRONG>Dashboard loads dynamically:</STRONG></P><pre class="lia-code-sample language-javascript"><code>import Card from "sap/ui/integration/widgets/Card";
const oCard = new Card({
manifest: "https://widgets.example.com/kpi-widget1/manifest.json",
baseUrl: "https://widgets.example.com/kpi-widget1"
});
oCard.placeAt("container");</code></pre><P> </P><P data-unlink="true"><STRONG>Why Integration Cards: </STRONG></P><P>Standardized format - Official SAPUI5 specification</P><P>Support Two card types:</P><UL><LI>Component cards: Full custom code for complex widgets</LI><LI>Declarative cards: Manifest-only (List, Table, Analytical, ...)</LI></UL><P>Built-in features: Headers, data binding, actions, error handling</P><P>Parameter passing: card.setParameters() with auto-refresh</P><P>Framework alignment: Native SAPUI5, team expertise, Fiori guidelines</P><P> </P><H1 id="toc-hId--514810064">Architecture Decision 3: Communication Patterns</H1><H2 id="toc-hId--1004726576">The Challenge: Bidirectional Communication</H2><P class="">Two-way communication required:</P><OL class=""><LI>Dashboard → Widgets: Apply filters to all widgets</LI><LI>Widgets → Dashboard: Handle user clicks (cross-filtering, navigation)</LI></OL><H3 id="toc-hId--1494643088"> </H3><H2 id="toc-hId--1397753586">Evaluated Patterns</H2><P><STRONG>Pattern 1: Pure EventBus</STRONG></P><pre class="lia-code-sample language-javascript"><code>import EventBus from "sap/ui/core/EventBus";
// SAP UI5 EventBus (pub/sub communication)
const eventBus = EventBus.getInstance();
eventBus.publish("filters", "changed", {
timeRange: "last7days" // For example
});</code></pre><P><STRONG>Pros: </STRONG>Loose coupling<STRONG><SPAN><BR />Cons: </SPAN></STRONG>State scattered in events</P><P> </P><P><STRONG>Pattern 2: State-Driven Reactive </STRONG></P><pre class="lia-code-sample language-javascript"><code>import JSONModel from "sap/ui/model/json/JSONModel";
// SAP UI5 JSON Model (client-side state)
const filterModel = new JSONModel({
timeRange: "last7days"
});</code></pre><P><STRONG>Pros: </STRONG>Single source of truth<STRONG><SPAN><BR />Cons: </SPAN></STRONG>Integration Cards don't support reactive binding</P><P> </P><P><SPAN><STRONG>Pattern 3: Host-Controlled</STRONG></SPAN></P><pre class="lia-code-sample language-javascript"><code>import Card from "sap/ui/integration/widgets/Card";
// SAP UI5 Integration Cards - trigger data refresh
cards.forEach((card) => card.refresh());</code></pre><P><SPAN><STRONG>Pros: </STRONG>Centralized control<STRONG><BR />Cons: </STRONG>Tight coupling</SPAN></P><P> </P><H3 id="toc-hId--1887670098">Our Solution: Hybrid EventBus + State-Driven</H3><P><STRONG>Best of both worlds:</STRONG></P><pre class="lia-code-sample language-javascript"><code>import JSONModel from "sap/ui/model/json/JSONModel";
import EventBus from "sap/ui/core/EventBus";
// SAP UI5 EventBus instance
const eventBus = EventBus.getInstance();
/**
* 1. Centralized State (Single Source of Truth)
* Shared JSONModel for filter state across the application
*/
const filterModel = new JSONModel({
timeRange: null,
category: [],
status: []
});
this.getView().setModel(filterModel, "filters");
/**
* 2. FilterBar → Update State + Publish Event
*/
onSearch() {
const filters = this.getFilterValues();
// Update centralized state
this.getModel("filters").setData(filters);
// Notify other components (no payload coupling)
eventBus.publish("app.filters", "changed", {
timestamp: new Date().toISOString()
});
}
/**
* 3. Dashboard → React to State Change
*/
onFiltersChanged() {
// Always read from centralized state (source of truth)
const filters = this.getModel("filters").getData();
// Update all Integration Cards (widgets)
this._cards.forEach((card) => {
card.setParameters(filters);
card.refresh(); // triggers data re-fetch + re-render
});
}</code></pre><P><STRONG>Pros:</STRONG></P><P>Single Source of Truth: Centralized filter state</P><P>Explicit Notifications: EventBus for change observation</P><P>Universal Support: Works with Component and Declarative cards</P><P>Debuggable: Inspect model state + trace events</P><P>Testable: Mock state and events independently</P><P> </P><H3 id="toc-hId--1915999912">Widget-to-Dashboard Communication</H3><P>Widgets fire action events on user interaction</P><pre class="lia-code-sample language-json"><code>{
"sap.card": {
"type": "List",
"content": {
"item": {
"title": "{name}",
"actions": [
{
"type": "Custom",
"parameters": {
"action": "viewDetails",
"id": "{id}",
"name": "{name}"
}
}
]
}
}
}
}</code></pre><P class=""><STRONG>Host (Dashboard) handle it</STRONG></P><pre class="lia-code-sample language-javascript"><code>oCard.attachAction((oEvent) => {
const action = oEvent.getParameter("action");
const params = oEvent.getParameter("parameters");
if (action === "Custom" && params.action === "viewDetails") {
// handle widget interaction
console.log("Item clicked:", params);
eventBus.publish("widget.item", "selected", params);
}
});</code></pre><P class=""><STRONG>Flow:</STRONG></P><OL class=""><LI>User clicks item in widget</LI><LI>Widget fires<SPAN> action event</SPAN></LI><LI>Dashboard receives event</LI><LI>Dashboard updates filter state</LI><LI>Dashboard publishes filter change</LI><LI>All widgets refresh with new filter</LI></OL><P> </P><H1 id="toc-hId--1525707403">Lessons Learned</H1><H3 id="toc-hId-1985940374">What Worked Well</H3><P><STRONG>Two-repository approach</STRONG></P><UL class=""><LI>True team independence</LI><LI>No merge conflicts</LI></UL><P>Deploy anytime without coordination</P><P><STRONG>SAPUI5 Integration Cards</STRONG></P><UL class=""><LI>Standardized pattern</LI><LI>Supports Component and Declarative types</LI><LI>Built-in features reduce boilerplate</LI></UL><P><STRONG>Hybrid communication</STRONG></P><UL class=""><LI>Centralized state = single source of truth</LI><LI>EventBus = loose coupling</LI><LI>Works with all card types</LI></UL><P><STRONG>Contract-based development</STRONG></P><UL class=""><LI>Registry acts as interface definition</LI><LI>Tags enable dynamic filtering</LI><LI>Clear responsibilities</LI></UL><P> </P><H1 id="toc-hId--1918734413">Results & Key Takeaways</H1><P class=""><STRONG>Achieved:</STRONG></P><UL class=""><LI>40+ widgets by 10+ teams</LI><LI>Independent deployment cycles</LI><LI>Zero downtime deployments</LI></UL><P class=""><STRONG>Key Insights:</STRONG></P><UL><LI><STRONG>Micro-frontends are organizational—</STRONG>they're about team autonomy and deployment independence, not just technology<STRONG>.</STRONG></LI><LI><STRONG>Match patterns to constraints—</STRONG>we chose Integration Cards because teams knew UI5, not because it's universally "best."</LI><LI><STRONG>Centralize wisely—</STRONG>filters are centralized (single source of truth), implementation is distributed (team autonomy).</LI><LI><STRONG>Contracts are your API—</STRONG>treat the widget registry with the same rigor as REST APIs.</LI></UL><P> </P><H2 id="toc-hId-1886316371">Resources</H2><P><STRONG>SAPUI5 Documentation:</STRONG></P><UL class=""><LI><A href="https://ui5.sap.com/test-resources/sap/ui/integration/demokit/cardExplorer/index.html" target="_blank" rel="noopener noreferrer">UI5 Integration Cards</A></LI><LI><A href="https://ui5.sap.com/#/api/sap.ui.core.EventBus" target="_blank" rel="noopener noreferrer">EventBus API</A></LI><LI><A href="https://ui5.sap.com/test-resources/sap/ui/integration/demokit/cardExplorer/webapp/index.html#/learn/typesOther/component" target="_blank" rel="noopener noreferrer">Component Cards</A></LI></UL><P class=""><STRONG>Micro-frontend Patterns:</STRONG></P><UL class=""><LI><A href="https://martinfowler.com/articles/micro-frontends.html" target="_blank" rel="noopener nofollow noreferrer">Micro Frontends by Martin Fowler</A></LI></UL><P> </P>2026-03-17T10:56:08.588000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/running-hugging-face-ai-models-with-sapui5-and-capm/ba-p/14350973Running Hugging Face AI Models with SAPUI5 and CAPM2026-03-19T15:59:27.461000+01:00Shrenath1903https://community.sap.com/t5/user/viewprofilepage/user-id/1630469<P> </P><P><STRONG>Hi everyone !</STRONG></P><P>After spending several hours researching and experimenting, I finally found a simple way to answer a question that many SAP developers have started asking:</P><P> “Is it possible to run AI models inside SAP applications using SAPUI5 and CAPM?”</P><P>The short answer is:</P><P><STRONG> Yes, absolutely!</STRONG></P><P>In this blog, I will share how we can integrate <STRONG>Hugging Face AI models with SAPUI5 and CAPM</STRONG>, and how we can build a simple AI-powered application that can generate <STRONG>text responses and even images</STRONG>.</P><P><STRONG>First Question: What is Hugging Face?</STRONG></P><P> If you are new to AI development, you might wonder:</P><P><STRONG>What exactly is Hugging Face?</STRONG></P><P>Think of <STRONG>Hugging Face as GitHub for AI models.</STRONG></P><P>It is a platform where developers and researchers publish and share machine learning models.</P><P>Currently, Hugging Face provides access to <STRONG>hundreds of thousands of AI models</STRONG> that can perform tasks such as:</P><UL><LI>Text generation</LI><LI>Chatbots</LI><LI>Image generation</LI><LI>Speech recognition</LI><LI>Translation</LI><LI>Code generation</LI></UL><P>The best part is that you can <STRONG>use these models directly through APIs</STRONG> without training your own model.</P><P>Another great advantage is that <STRONG>Hugging Face provides GPU infrastructure</STRONG>, which means you can run advanced models without owning expensive hardware.</P><P>And yes — if you build your own model, you can also <STRONG>publish it on Hugging Face and make it available globally.</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_1-1773748224278.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384722iF2F7B9FE79172ED3/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_1-1773748224278.png" alt="Shrenath1903_1-1773748224278.png" /></span></P><P> Fig 1.1 Hugging Face Models sections</P><P> </P><P><STRONG>Now the Interesting Part: Can SAPUI5 Use AI?</STRONG></P><P>When I started this experiment, my first question was:</P><P><STRONG>Can SAPUI5 directly call an AI model?</STRONG></P><P>The answer is <STRONG>yes</STRONG>, especially for <STRONG>text generation models</STRONG>.</P><P>To make this work, we only need three things:</P><P>- A <STRONG>Hugging Face account</STRONG><BR />- An <STRONG>HF API Token</STRONG><BR />- A <STRONG>model endpoint</STRONG></P><P>Once you log in to Hugging Face, you can generate an <STRONG>HF Token</STRONG> from your account settings.</P><P>Then you can choose any model depending on your use case. Hugging Face provides model benchmarks and descriptions, so you can easily decide which one is best for:</P><UL><LI>Education</LI><LI>Coding</LI><LI>Reasoning</LI><LI>Chat</LI><LI>Content generation</LI></UL><P><STRONG>Connecting Hugging Face with SAPUI5</STRONG></P><P>Now let's talk about the implementation.</P><P>In the <STRONG>SAPUI5 controller</STRONG>, we can send a request to the Hugging Face API using JavaScript fetch().</P><P>The UI simply takes a <STRONG>user prompt</STRONG>, sends it to the AI model, and displays the response.</P><P>Example flow:</P><P>User enters a prompt:</P><P> "What is Hugging Face and SAPUI5?"</P><P>SAPUI5 sends the prompt to the Hugging Face model.</P><P>The model generates a response and returns it.</P><P>Then SAPUI5 displays the result directly on the UI.</P><P>This makes it very easy to build <STRONG>AI chat assistants inside SAP applications.</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_2-1773748300320.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384723iADE0FE872262BC31/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_2-1773748300320.png" alt="Shrenath1903_2-1773748300320.png" /></span></P><P> Fig 1.2 Output- Hugging Face Ai Chat</P><P> </P><P>Sample Code:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_3-1773748319144.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384724i0BB44A0392EB41E2/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_3-1773748319144.png" alt="Shrenath1903_3-1773748319144.png" /></span></P><P> Fig 1.3 sapui5 Controller.js - Hugging Face Ai Chat</P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_4-1773748334826.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384726iB74F6BEF535D00CF/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_4-1773748334826.png" alt="Shrenath1903_4-1773748334826.png" /></span></P><P> Fig 1.3 sapui5 view.xml - Hugging Face Ai Chat</P><P> </P><P><STRONG>But What About Image Generation?</STRONG></P><P>This is where things become interesting.</P><P>When I tried running <STRONG>image generation models directly in SAPUI5</STRONG>, I realized something important.</P><P><span class="lia-unicode-emoji" title=":warning:">⚠️</span><STRONG>SAPUI5 works best with text-based AI APIs.</STRONG></P><P>For <STRONG>image generation models</STRONG>, we need a backend service.</P><P>This is where <STRONG>CAPM (Cloud Application Programming Model)</STRONG> becomes very useful.</P><P> </P><P> </P><P><STRONG>Using CAPM for Image Generation</STRONG></P><P>To generate images, we can integrate <STRONG>fal.ai</STRONG>, which provides inference APIs for advanced image generation models.</P><P>Some examples include:</P><UL><LI><STRONG>black-forest-labs / FLUX.1-dev</STRONG></LI><LI><STRONG>Tongyi-MAI / Z-Image-Turbo</STRONG></LI></UL><P>These models can generate high-quality AI images from text prompts.</P><P><STRONG>For example:</STRONG></P><P>"Portrait of a futuristic astronaut with glowing blue eyes"</P><P>The system sends this prompt to the AI model, and the model generates an image.</P><P> </P><P><STRONG>How CAPM Handles This</STRONG></P><P>Inside the <STRONG>CAPM Node.js service</STRONG>, we create a custom action such as:</P><P> "generateImage"</P><P>This action receives the prompt from SAPUI5.</P><P>Then CAPM calls the <STRONG>fal.ai API</STRONG> with that prompt.</P><P>The AI model generates the image and returns a <STRONG>URL of the generated image</STRONG>, which we send back to the UI.</P><P>This makes CAPM act as a <STRONG>bridge between SAPUI5 and AI models.</STRONG></P><P> </P><P><STRONG>Why Use fal.ai Instead of Hugging Face Directly?</STRONG></P><P>You might ask:</P><P><STRONG> If we already use Hugging Face, why do we need fal.ai?</STRONG></P><P> Good question.</P><P>Some models listed on Hugging Face are actually <STRONG>hosted through different inference providers</STRONG>, including fal.ai.</P><P><STRONG>For example:</STRONG></P><P>black-forest-labs / FLUX.1-dev</P><P>This model is often executed through <STRONG>fal.ai inference APIs</STRONG>.</P><P>So fal.ai becomes an <STRONG>easy way to run those models with strong GPU performance.</STRONG></P><P><STRONG>Sample Code:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_5-1773748428535.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384728iA9375C72C81334F6/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_5-1773748428535.png" alt="Shrenath1903_5-1773748428535.png" /></span></P><DIV class=""> </DIV><P>Fig 1.4 Output – CAPM - Hugging face Image generation</P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_8-1773748474519.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384731i6B7AC92E939A9465/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_8-1773748474519.png" alt="Shrenath1903_8-1773748474519.png" /></span></P><P>Fig 1.5 service.js - first half- Hugging face Image generation</P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_9-1773748485576.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384733iF9C166F2CBE78E64/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_9-1773748485576.png" alt="Shrenath1903_9-1773748485576.png" /></span></P><P>Fig 1.6 service.js - second half - Hugging face Image generation</P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shrenath1903_10-1773748497730.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384734iB5F1F66CD0364EC1/image-size/medium?v=v2&px=400" role="button" title="Shrenath1903_10-1773748497730.png" alt="Shrenath1903_10-1773748497730.png" /></span></P><P>Fig 1.7 Fal.ai API key Generation - Hugging face Image generation</P><P> </P><P><STRONG>Final Result</STRONG></P><P>After connecting everything together, we get a simple AI application:</P><P>The application can:</P><P>- Generate <STRONG>AI text responses using SAPUI5</STRONG><BR />- Generate <STRONG>AI images using CAPM services</STRONG><BR />- Use <STRONG>Hugging Face models</STRONG><BR />- Run <STRONG>without training your own model</STRONG></P><P>All of this can be done using <STRONG>free developer APIs</STRONG>, unless you need large-scale GPU workloads.</P><P> </P><P><STRONG>Conclusion</STRONG></P><P>From this experiment, we can see that <STRONG>SAP applications can easily integrate with modern AI platforms.</STRONG></P><P>The architecture becomes very simple:</P><P><STRONG> SAPUI5</STRONG><BR /> ⬇<BR /><STRONG> CAPM Service</STRONG><BR /> ⬇<BR /><STRONG> Hugging Face / fal.ai AI Models</STRONG></P><P> </P><P>Using this approach, developers can build powerful applications such as:</P><UL><LI>AI chat assistants inside SAP</LI><LI>AI-powered knowledge systems</LI><LI>Image generation tools</LI><LI>Smart enterprise automation</LI></UL><P>And the best part is that <STRONG>you can even deploy your own AI model on Hugging Face and use it inside SAP applications.</STRONG></P><P> </P><P>I hope this small experiment helps other developers who are curious about <STRONG>AI + SAP integration.</STRONG></P><P>Happy coding! </P><P> </P><P> </P><P> </P>2026-03-19T15:59:27.461000+01:00https://community.sap.com/t5/technology-blog-posts-by-sap/sap-user-experience-q1-2026-update-part-9-ui-design-and-technology-for-web/ba-p/14355574SAP User Experience Q1/2026 Update – Part 9: UI Design and Technology for Web and Mobile2026-03-23T09:53:54.363000+01:00ThomasReisshttps://community.sap.com/t5/user/viewprofilepage/user-id/149639<P><STRONG>This ninth and last post in my series gives an overview innovations in our UI tools and technologies, making it ever easier to design, build and integrate UIs, for both web and mobile applications. For designing apps, web and mobile, we have added AI content and more to the SAP Design System portal and UI Kits in Figma. For web developers, we have introduced the SAP Fiori development portal, as well as more AI support via MCP servers for SAPUI5 and for SAP Fiori elements, and Joule integration. Beyond that: have a look at how you can use AI to migrate to TypeScript, learn about the new Geomap control, and benefit from the new SAPUI5 runtime repository. </STRONG><STRONG>Finally, discover the latest updates for mobile design and development with our SDKs and the mobile development kit.</STRONG></P><P>Joule can also be seen as a technology for delivering a great user experience. To find out about recent innovations there, as well as for central entry points and services, have a look at this post, which also contains links to all the other parts of the series:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-ux-q3-2025-update-part-1-ai-joule-sap-build-work-zone-sap-mobile-start/ba-p/14161847" target="_blank">SAP UX Q3/2025 Update – Part 1: AI, Joule, SAP Build Work Zone, SAP Mobile Start</A>.</LI></UL><P>In case you missed them, do have a look at my previous posts covering design and technology news, since what I mention here builds partly on what came before:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-user-experience-q1-2025-update-part-7-ui-design-and-technology-for-web/ba-p/14034290" target="_blank">SAP User Experience Q1/2025 Update – Part 7: UI Design and Technology for Web and Mobile</A>. This post has a lot of information about extensibility, especially for SAP S/4HANA Cloud Public Edition. Do also have a look at the new <A href="https://extensibilityexplorer.cfapps.eu10.hana.ondemand.com/ExtensibilityExplorer/" target="_blank" rel="noopener nofollow noreferrer">SAP Extensibility Explorer</A>.</LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-ux-q3-2025-update-part-7-ui-design-and-technology-for-web-and-mobile/ba-p/14197128" target="_blank">SAP UX Q3/2025 Update – Part 7: UI Design and Technology for Web and Mobile</A>.</LI></UL><P>First, we’ll have a look at news for creating web UIs, before looking at what’s new for mobile design and development.</P><P> </P><H1 id="toc-hId-1663302467">News for Creating Web UIs</H1><P>I’ve compiled the news into these sections:</P><UL><LI>SAP Design System Portal and UI Kits – now with AI UI Elements.</LI><LI>SAP Fiori Development Portal.</LI><LI>Using AI to Develop UIs – MCP Servers, Joule.</LI><LI>SAP Fiori Tools News.</LI></UL><H2 id="toc-hId-1595871681">SAP Design System Portal and UI Kits – now with AI UI Elements</H2><P>We recently introduced the new <A href="http://www.sap.com/design-system" target="_blank" rel="noopener noreferrer">SAP Design System portal</A> that brings together the product design guidelines SAP Fiori for web, SAP Fiori for iOS, and SAP Fiori for Android, as well as to the new digital design system guidelines. With its enhanced usability, simplified versioning and improved performance, designers (and developers!) get a better user experience compared with the previous SAP Fiori design guidelines.</P><P>End of last year we introduced these AI UI elements for web UIs, as you can see in Figure 1 below:</P><UL><LI>AI Acknowledgement.</LI><LI>AI Button.</LI><LI>AI Writing Assistant.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Figure 1: AI UI elements available in SAP Design System portal. Alt Text: Screenshot of the portal UI Elements page with a filter at the top containing “AI”, below that “3 results” showing three cards in a horizontal row for “AI Acknowledgement”, “AI Button” and “AI Writing Assistant”." style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/387530i76E84DA5E4BEC9A1/image-size/large?v=v2&px=999" role="button" title="01 Design System Portal - AI UI elements.png" alt="Figure 1: AI UI elements available in SAP Design System portal. Alt Text: Screenshot of the portal UI Elements page with a filter at the top containing “AI”, below that “3 results” showing three cards in a horizontal row for “AI Acknowledgement”, “AI Button” and “AI Writing Assistant”." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Figure 1: AI UI elements available in SAP Design System portal. Alt Text: Screenshot of the portal UI Elements page with a filter at the top containing “AI”, below that “3 results” showing three cards in a horizontal row for “AI Acknowledgement”, “AI Button” and “AI Writing Assistant”.</span></span></P><P>Get a complete overview of what’s new in the design system portal here</P><UL><LI><A href="https://www.sap.com/design-system/fiori-design-web/v1-145/discover/whats-new" target="_blank" rel="noopener noreferrer">What’s New in the SAP Design System Portal?</A></LI></UL><H3 id="toc-hId-1528440895">UI Kits v8.0 and v9.0 – now with AI components</H3><P>The new UI Kits available for designers in Figma make it easy for designers to design accessible UIs at enterprise scale, for web applications, mobile iOS and Android applications as well as wearables. The UI Kits provide reusable components for web and mobile, along with web floorplans, which give you what you need out-of-the-box.</P><P>In the meantime, we have released SAP Web UI Kit v8.0 which includes a full set of <STRONG>AI components</STRONG>: AI Button, AI Menu Button, AI Split Menu Button, AI Input, and AI Text Area.</P><P>The latest release, <A href="https://www.figma.com/community/file/1494295794601744471" target="_blank" rel="noopener nofollow noreferrer">SAP Web UI Kit v9.0</A>, continues to evolve the system with focused improvements that enhance visual quality, usability, and overall consistency across the kit. It brings:</P><UL><LI><STRONG>Updated Icons:</STRONG><BR />All icons have been refreshed with a 1.5px stroke (down from 1.6px). This improves anti-aliasing and results in cleaner, sharper visuals across interfaces.</LI><LI><STRONG>Busy Indicator Enhancements:</STRONG><BR />You now have two Busy Indicator options, static and animated, available on the same page. The <STRONG>new animated version</STRONG> is ready to use out of the box, saving time and implementation effort.</LI><LI><STRONG>Redesigned Color Palette. </STRONG>Note that the previous color palette component has been removed in order to avoid confusion, and keep the kit cleaner and easier to navigate.</LI></UL><P>Find out more here:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/new-sap-design-system-portal-for-sap-fiori-design-guidelines-and-new-ui/ba-p/14109558" target="_blank">New SAP Design System Portal for SAP Fiori Design Guidelines, and New UI Kits for Designers</A>.</LI></UL><H2 id="toc-hId-1202844671">SAP Fiori Development Portal</H2><P>I’m also happy to inform you about the new SAP Fiori development portal. It is designed to help developers maximize the benefits of SAP Fiori elements for OData V4, which is more than just a UI framework: it’s a metadata-driven approach that leverages the <A href="https://www.sap.com/design/design-system" target="_blank" rel="noopener noreferrer">SAP Design System</A> as its guiding principle, incorporating the most relevant design system options for typical business tasks.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Figure 2: The SAP Fiori development portal. Alt text: A screenshot showing the Introduction page. On the left a menu has entries Using the Portal, Building Blocks, Global Patterns, Floorplans, SAP Fiori Tools. The Introduction page has a full width card “Building Blocks” at the top, with a description and tiles representing various building blocks. Below that “Choose Your Option” heading above two side-by-side cards for “Floorplans” and “Customer Layout”, each with an image and description, and a “Learn More” button." style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/387531i5683123CA13D48E5/image-size/large?v=v2&px=999" role="button" title="02 SAP Fiori development portal.jpg" alt="Figure 2: The SAP Fiori development portal. Alt text: A screenshot showing the Introduction page. On the left a menu has entries Using the Portal, Building Blocks, Global Patterns, Floorplans, SAP Fiori Tools. The Introduction page has a full width card “Building Blocks” at the top, with a description and tiles representing various building blocks. Below that “Choose Your Option” heading above two side-by-side cards for “Floorplans” and “Customer Layout”, each with an image and description, and a “Learn More” button." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Figure 2: The SAP Fiori development portal. Alt text: A screenshot showing the Introduction page. On the left a menu has entries Using the Portal, Building Blocks, Global Patterns, Floorplans, SAP Fiori Tools. The Introduction page has a full width card “Building Blocks” at the top, with a description and tiles representing various building blocks. Below that “Choose Your Option” heading above two side-by-side cards for “Floorplans” and “Customer Layout”, each with an image and description, and a “Learn More” button.</span></span></P><P>The SAP Fiori development portal puts building blocks front and center. These building blocks - such as tables, forms, filter bars, and charts - are orchestrated by SAP Fiori elements and form the basis of every OData V4 application. They provide standardized layouts and interaction patterns, ensuring UI consistency and boosting developer productivity. The great advantage of using building blocks is that you can use them to create a customer layout and yet still benefit from the advantages of the metadata driven approach: low code, built in enterprise-grade capabilities such as multi-language support, accessibility, security and performance, and design system consistency.</P><P>Find out more in this six-part series of blog posts, here is the first one, which contains links to the others:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-sap-fiori-development-portal-your-gateway-to-rapid-sap/ba-p/14236768" target="_blank">Introducing the SAP Fiori Development Portal: Your Gateway to Rapid SAP Fiori App Creation (1 of 6)</A>.</LI></UL><P>We have also restructured our documentation for SAP Fiori elements, with separate entry points for OData V4 and OData V2, and better supporting the building block approach. Read more here:</P><UL><LI><A class="" href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-fiori-elements-new-documentation-structure/ba-p/14344845" target="_blank">SAP Fiori Elements: New Documentation Structure</A>.</LI></UL><H2 id="toc-hId-1006331166">Using AI to Develop UIs – MCP Servers, Joule</H2><P>The above posts from <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-user-experience-q1-2025-update-part-7-ui-design-and-technology-for-web/ba-p/14034290" target="_blank">Q1/2025</A> and <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-ux-q3-2025-update-part-7-ui-design-and-technology-for-web-and-mobile/ba-p/14197128" target="_blank">Q3/2025</A> introduced a number of powerful ways to accelerate UI development by using AI, such as:</P><UL><LI>Creating SAP Fiori elements apps from a sketch (in the Q1 post), now integrated in SAP Build Code and Joule (Q3 post)</LI><LI>Joule for SAPUI5 freestyle development (Q1 post)</LI><LI>AI-assisted auto-fix of coding errors with UI5 linter (Q3 post)</LI></UL><P>Recently, we have gone even further and introduced MCP servers for freestyle SAPUI5 development as well as for developing with SAP Fiori elements and the associated building blocks. These open-source <A href="https://modelcontextprotocol.io/" target="_blank" rel="noopener nofollow noreferrer">Model Context Protocol (MCP)</A> servers provide AI agents with comprehensive UI5 and SAP Fiori elements knowledge, including best practices and project-aware context information, and thus provide developers with valuable support. Figure 3 shows examples.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Figure 3: Examples of the UI5 MCP Server (on the left) and the MCP Server for SAP Fiori (on the right) in action. Alt Text: both images show screenshots of a CLINE console view with a task entered as text at the top, followed by a list of steps which the system proposes to do to solve the task." style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/387533i1F04C12D27460469/image-size/large?v=v2&px=999" role="button" title="03 MCP Servers UI5 and Fiori.jpg" alt="Figure 3: Examples of the UI5 MCP Server (on the left) and the MCP Server for SAP Fiori (on the right) in action. Alt Text: both images show screenshots of a CLINE console view with a task entered as text at the top, followed by a list of steps which the system proposes to do to solve the task." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Figure 3: Examples of the UI5 MCP Server (on the left) and the MCP Server for SAP Fiori (on the right) in action. Alt Text: both images show screenshots of a CLINE console view with a task entered as text at the top, followed by a list of steps which the system proposes to do to solve the task.</span></span></P><P>Read about these new MCP servers in these blog posts:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/give-your-ai-agent-some-tools-introducing-the-ui5-mcp-server/ba-p/14200825" target="_blank">UI5 MCP Server</A>.</LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-fiori-tools-update-first-release-of-the-sap-fiori-mcp-server-for/ba-p/14204694" target="_blank">MCP Server for SAP Fiori</A>.</LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-members/setting-the-right-expectations-around-ai-for-code-generation-and-getting/ba-p/14327300" target="_blank">Setting the right expectations around AI for code generation and getting past the inherent limits</A></LI></UL><P>Alternatively, you can listen to these podcasts involving Tim Back and Florian Vogt, talking about the intricacies of the Model Context Protocol (MCP) within the SAP ecosystem:</P><UL><LI>Spotify: <A href="https://open.spotify.com/episode/1Z1GTmFqY5P5Va3T8t33RG?si=mDX84dfwQmi_NrhkXvxtzg" target="_blank" rel="noopener nofollow noreferrer">UI5 & MCP - Navigating the Model Context Protocol in SAP</A>.</LI><LI>Apple Podcast: <A href="https://podcasts.apple.com/us/podcast/ui5-mcp-navigating-the-model-context-protocol-in-sap/id1535460646?i=1000749280589" target="_blank" rel="noopener nofollow noreferrer">UI5 & MCP - Navigating the Model Context Protocol in SAP</A>.</LI></UL><H3 id="toc-hId-938900380">Latest UI5 MCP Server Enhancements</H3><P>The UI5 MCP server got extended to help migrate existing JavaScript code to TypeScript, as well as for generating UI Integration Cards.</P><P><STRONG>New TypeScript Migration Feature</STRONG></P><P>With the newest feature of the UI5 MCP server, UI5-specific TypeScript conversion assistance is now available to AI coding agents, making the task much easier. Find out more in this blog post:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/ui5-mcp-server-s-new-typescript-migration-feature-real-world-experience-and/ba-p/14289451" target="_blank">UI5 MCP Server's New TypeScript Migration Feature - Real-World Experience and Best Practices</A></LI></UL><P><STRONG>Generating UI Integration Cards</STRONG></P><P>The UI5 MCP Server now supports the development of UI Integration Cards. In its latest version – v0.2.1 – it includes three new tools dedicated to UI Integration Cards:</P><OL><LI>Best practice guidance for your agent.</LI><LI>Scaffolding a new Integration Card.</LI><LI>Validating the Card’s manifest.</LI></OL><P>These tools assist Large Language Models (LLMs) in creating new cards from scratch or editing existing ones, following the best practices for card development. Find out more here:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/ui5-mcp-server-got-extended-for-ui-integration-cards-generation/ba-p/14312670" target="_blank">UI5 MCP Server Got Extended for UI Integration Cards Generation</A>.</LI></UL><H3 id="toc-hId-742386875">AI News for SAP Fiori Tools and MCP Server for SAP Fiori</H3><P>The <A href="https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/6845fedbb38c4da7a54a2c76081f3abb.html" target="_blank" rel="noopener noreferrer">Project Accelerator</A> can now be launched directly from the SAP Fiori generator, streamlining the initial project creation flow. The previously required staging step has been removed, allowing new projects to be created directly in the selected workspace folder. For projects created using the Project Accelerator, the Application Modeler now offers advanced editing capabilities, such as creating new fields and properties end-to-end, updating the data model, exposing the service, and consuming the changes in the UI in one coherent flow.</P><P>AI support has also been extended to mock data generation. Developers can generate realistic mock data using AI directly in the Application Modeler, and this capability is available for all applications whenever the Project Accelerator is enabled.</P><P>In parallel, the <A href="https://www.npmjs.com/package/@sap-ux/fiori-mcp-server" target="_blank" rel="noopener nofollow noreferrer">MCP server for SAP Fiori</A> continues to expand. The server now exposes <A href="https://www.npmjs.com/package/@sap-ux/create" target="_blank" rel="noopener nofollow noreferrer">@sap-ux/create</A> commands as CLI functionality, enabling reliable execution in MCP-supported workflows. App generation has been extended to support CAP Java projects, and a new “search_docs” tool allows the LLM (Large Language Model) to query SAP Fiori elements documentation, annotations, SAP Fiori tools documentation, and SAP Fiori Development Portal resources to quickly find relevant guidance and code snippets.</P><H3 id="toc-hId-545873370">Joule Enhancement: Create Freestyle SAPUI5 Apps in SAP Build Code</H3><P>You can now use Joule in SAP Build Code to create new freestyle SAPUI5 apps according to your requirements. The feature is not absolutely groundbreaking, as there are other tools doing a similar job like the <A href="https://github.com/ui5-community/generator-easy-ui5" target="_blank" rel="noopener nofollow noreferrer">Easy-UI5 templates</A> and the recently published <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/give-your-ai-agent-some-tools-introducing-the-ui5-mcp-server/ba-p/14200825" target="_blank">UI5 MCP Server</A>. But:</P><OL><LI>It brings the functionality right to the fingertips of developers using SAP Build Code – no other tools needed.</LI><LI>It extends the template capabilities beyond what the Easy-UI5 templates provide.</LI><LI>Implementing it within the Build Code Joule environment yielded interesting insights and further improvements.</LI></OL><P>Find out more about the feature, and in the second “making of” post, read about how Andreas Kunz went about building it, and what he learnt from doing it:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/joule-in-sap-build-code-can-now-create-freestyle-ui5-apps/ba-p/14264445" target="_blank">Joule in SAP Build Code can now create freestyle UI5 apps</A>.</LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/inside-joule-lessons-from-building-an-ai-coding-assistant-for-sap-build/ba-p/14264447" target="_blank">Inside Joule: Lessons from building an AI coding assistant for SAP Build</A>.</LI></UL><H2 id="toc-hId-220277146">SAP Fiori Tools News</H2><P>In addition to the AI-enhancements mentioned above, we now provide expanded support for SAP Fiori elements building blocks, a new connection manager for SAP Systems in VS Code, and a feature to preview SAP Fiori web apps on mobile devices.</P><H3 id="toc-hId-152846360">Expanded Support for SAP Fiori Elements Building Blocks</H3><P>The following enhancements make it easier to adapt applications and allow developers to work more confidently and efficiently with SAP Fiori elements–based UIs.</P><P>Developers can now add more building block types to their apps with the Page Editor, including</P><UL><LI>rich text editors within custom sections,</LI><LI>custom columns for table building blocks, and</LI><LI>the page building block itself.</LI></UL><P>Managing custom pages is also more intuitive, as building blocks can now be deleted directly from the editor.</P><P>To support experimentation and iteration, <STRONG>undo</STRONG> and <STRONG>redo</STRONG> actions are now available when working on custom pages.</P><H3 id="toc-hId--118898514">New Connection Manager for SAP Systems in VS Code</H3><P>We have introduced the <A href="https://marketplace.visualstudio.com/items?itemName=SAPOSS.sap-ux-sap-systems-ext" target="_blank" rel="noopener nofollow noreferrer">Connection Manager</A> for SAP Systems as a dedicated Visual Studio Code extension for managing connections to remote SAP systems. The Connection Manager allows developers to create, store, test, and edit connection information that can be reused by the SAP Fiori generator as well as by preview features in SAP Fiori tools.</P><H3 id="toc-hId--315412019">Preview SAP Fiori Web Apps on Mobile</H3><P>When developing SAP Fiori applications, simulating a mobile experience in a desktop browser often isn’t enough to fully validate real-world behavior. Touch interactions, performance characteristics, and device-specific rendering can differ noticeably on physical phones and tablets.</P><P>To address this, SAP Fiori tools now supports previewing applications directly on real mobile devices. You do this by using <A href="https://www.npmjs.com/package/@sap/ux-ui5-tooling" target="_blank" rel="noopener nofollow noreferrer">@sap/ux-ui5-tooling</A> version 1.19.1 or higher and creating a new run configuration and enabling Remote Access. When you start the run configuration, the terminal provides connection details, including a URL and a QR code, which can be opened directly on a phone or tablet to access the running app.</P><P>Find out more here:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-fiori-tools-2601-update-mobile-device-preview-building-blocks-and-ai/ba-p/14292653" target="_blank">SAP Fiori tools 2601 update – Mobile Device Preview, Building Blocks, and AI-Driven Productivity</A><SPAN>.</SPAN></LI><LI><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-january-2026-issue-38/ba-p/14304753" target="_blank">SAP Fiori Development newsletter January 2026 (issue #38)</A>.</LI><LI><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/sap-fiori-development-newsletter-issue-39-march-2026/ba-p/14334703" target="_blank">SAP Fiori Development newsletter issue #39 (March 2026)</A>.</LI></UL><P> </P><H1 id="toc-hId-74880490">News for Mobile Designers and Developers</H1><P>Let’s first look at updates in the design guidelines and the SDKs, and then look at news for the mobile development kit (MDK).</P><H2 id="toc-hId--415036022">Mobile Design Guideline and SDK Updates</H2><P>We have introduced numerous new and enhanced patterns and components this last half-year. I have selected a small number to highlight here, further below you’ll find links to get the full overview.</P><H3 id="toc-hId--904952534">New for AI</H3><P>The following two new patterns have been introduced for both the SAP Fiori for Android and the SAP Fiori for iOS design guidelines.</P><P><STRONG>AI Insights Pattern:</STRONG> We have introduced a new AI Insights Pattern, which describes how to present AI insights optimally on mobile devices, as shown in Figure 4. It provides a standardized way to display a summary, analysis, or suggestion generated with AI. This pattern can be applied to a full-screen or a card depending on the scope of content generated by AI.</P><P><STRONG>AI Handoff Pattern</STRONG>: We have created a new guideline describing the AI Handoff Pattern, which defines how a user should transition between contextual embedded AI features and the Joule conversational panel.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Figure 4: Two new AI patterns: AI Insights Pattern and AI Handoff Pattern. Alt Text: On the left two image for AI Insights Pattern, first a full mobile phone screen with title and subtitle at the top, followed by two insights sections, each with two slots for content, at the bottom a user feedback row with thumbs up and thumbs down icons, above a an AI generate button. On the right a diagram for the AI Handoff Pattern showing a schematic mobile module with arrow to and from a schematic Joule UI." style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/387534iCF6B5B412E5A2C96/image-size/large?v=v2&px=999" role="button" title="04 Mobile - AI patterns.jpg" alt="Figure 4: Two new AI patterns: AI Insights Pattern and AI Handoff Pattern. Alt Text: On the left two image for AI Insights Pattern, first a full mobile phone screen with title and subtitle at the top, followed by two insights sections, each with two slots for content, at the bottom a user feedback row with thumbs up and thumbs down icons, above a an AI generate button. On the right a diagram for the AI Handoff Pattern showing a schematic mobile module with arrow to and from a schematic Joule UI." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Figure 4: Two new AI patterns: AI Insights Pattern and AI Handoff Pattern. Alt Text: On the left two image for AI Insights Pattern, first a full mobile phone screen with title and subtitle at the top, followed by two insights sections, each with two slots for content, at the bottom a user feedback row with thumbs up and thumbs down icons, above a an AI generate button. On the right a diagram for the AI Handoff Pattern showing a schematic mobile module with arrow to and from a schematic Joule UI.</span></span></P><H3 id="toc-hId--1101466039">Further news</H3><P>I have picked two stand-out updates, also made available for Android and iOS.</P><P><STRONG>New Illustrations:</STRONG> We have introduced the new illustrations, that were also introduced in the web, to the mobile design system and the mobile SDKs. You can see a few examples on the left in Figure 5 below.</P><P><STRONG>More flexible card layouts: </STRONG>We offer far more flexibility now in how you use cards to summarize information. For example, you can create wider cards that have the image on the left or the right, and the content block next to it. With the new <STRONG>flex item</STRONG> component, the card’s main header can now be customized to hold more content by adding tags and status info labels outside, on top, between, or below the title and subtitle. Two examples are shown in Figure 5 on the right.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Figure 5: New illustrations and more flexible card layout and content options. Alt Text: On the left three different-size “My Daily Tasks” cards, with images for “You’r all caught up”, “Oops” and “Congratulations”. On the right two card examples: at the top a slim wide card with title, subtitle and one line text on the left, image on the right; below that a larger card with image on the left, title and details with colored indicators and buttons on the right." style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/387536iCE3157E5165EF5F9/image-size/large?v=v2&px=999" role="button" title="05 Mobile - illustrations and cards.jpg" alt="Figure 5: New illustrations and more flexible card layout and content options. Alt Text: On the left three different-size “My Daily Tasks” cards, with images for “You’r all caught up”, “Oops” and “Congratulations”. On the right two card examples: at the top a slim wide card with title, subtitle and one line text on the left, image on the right; below that a larger card with image on the left, title and details with colored indicators and buttons on the right." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Figure 5: New illustrations and more flexible card layout and content options. Alt Text: On the left three different-size “My Daily Tasks” cards, with images for “You’r all caught up”, “Oops” and “Congratulations”. On the right two card examples: at the top a slim wide card with title, subtitle and one line text on the left, image on the right; below that a larger card with image on the left, title and details with colored indicators and buttons on the right.</span></span></P><P>Find out more here:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-sap-fiori-for-android-ios-25-8-innovative-enhancements-for/ba-p/14227276" target="_blank">Introducing SAP Fiori for Android/iOS 25.8: Innovative Enhancements for Android and iOS</A>.</LI></UL><P>For an overview of all updates, have a look at the what’s new sections in the SAP Design System portal and the SAP Mobile Services Documentation</P><UL><LI>SAP Fiori for Android design: <A href="https://www.sap.com/design-system/fiori-design-android/v26-1/discover/what-is-new" target="_blank" rel="noopener noreferrer">What's New for SAP BTP SDK for Android 26.1 and older</A>.</LI><LI>SAP BTP SDK for Android: <A href="https://help.sap.com/doc/f53c64b93e5140918d676b927a3cd65b/Cloud/en-US/docs-en/about/releases/android/whats-new.html" target="_blank" rel="noopener noreferrer">What’s New in Release 26.1.2 and earlier releases</A>.</LI><LI>SAP Fiori for iOS design: <A href="https://www.sap.com/design-system/fiori-design-ios/v26-1/discover/what-is-new" target="_blank" rel="noopener noreferrer">What's New for SAP BTP SDK for iOS 26.1 and older</A>.</LI><LI>SAP BTP SDK for iOS: <A href="https://help.sap.com/doc/f53c64b93e5140918d676b927a3cd65b/Cloud/en-US/docs-en/about/releases/ios/whats-new.html" target="_blank" rel="noopener noreferrer">What’s New in Version 26.1.2 and earlier releases</A>.</LI></UL><H2 id="toc-hId--1004576537">Mobile Development Kit (MDK) News</H2><P>The Mobile Development Kit, available as part of SAP Mobile Services, enables developers and technical business users to build cross-platform mobile applications. It allows you to build your application once, in an integrated development environment (SAP Business Application Studio / VSCode extension) and run it natively on Mobile Android and iOS devices. </P><P>Here I have chosen to highlight one area: enhancements to the calander control, which now supports date range selection as well as allowing you to highlight special events or statuses directly on the calendar.</P><P>The new date range selection displays the calendar in a month-view format and allows multiple months to be shown. Users can scroll vertically through the calendar months. This is ideal if you need to plan events or manage schedules over extended periods, since users can select a time period with a start date and an end date (see Figure 6 below):</P><UL><LI>The <STRONG>first date</STRONG> selected becomes the <STRONG>start date</STRONG> of the range.</LI><LI>The <STRONG>second date</STRONG> selected becomes the <STRONG>end date </STRONG>of the range.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Figure 6: Date range selection supported by the mobile development kit provided by SAP Mobile Service. Alt Text: An image of an iPhone and an Android phone next to each other. The iPhone with the light Morning Horizon theme and a date selection Sep 16 – Sep 29, 2025, the other with the dark Evening Horizon theme and a date selection Mon Sep 29 to Fri Oct 17 2025." style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/387539iA9161620ABFF1CD1/image-size/large?v=v2&px=999" role="button" title="06 MDK DateRange.jpg" alt="Figure 6: Date range selection supported by the mobile development kit provided by SAP Mobile Service. Alt Text: An image of an iPhone and an Android phone next to each other. The iPhone with the light Morning Horizon theme and a date selection Sep 16 – Sep 29, 2025, the other with the dark Evening Horizon theme and a date selection Mon Sep 29 to Fri Oct 17 2025." /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Figure 6: Date range selection supported by the mobile development kit provided by SAP Mobile Service. Alt Text: An image of an iPhone and an Android phone next to each other. The iPhone with the light Morning Horizon theme and a date selection Sep 16 – Sep 29, 2025, the other with the dark Evening Horizon theme and a date selection Mon Sep 29 to Fri Oct 17 2025.</span></span></P><P>Find out more here:</P><UL><LI>Blog post: <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/what-s-new-in-mobile-development-kit-client-25-9/ba-p/14227370" target="_blank">What’s new in Mobile development kit client 25.9</A>.</LI><LI>Documentation: <A href="https://help.sap.com/doc/f53c64b93e5140918d676b927a3cd65b/Cloud/en-US/docs-en/about/releases/mdk/whats-new.html" target="_blank" rel="noopener noreferrer">What’s New in Mobile Development Kit 25.9.1 and earlier releases</A>.</LI></UL><P> </P><H1 id="toc-hId--907687035">Further Information</H1><P>For creating web applications, do register for the upcoming <A href="https://openui5.org/ui5con/index.html" target="_blank" rel="noopener nofollow noreferrer">UI5con</A> virtual conference.</P><P>Learn more about it at <A href="https://openui5.org/ui5con/faq.html" target="_blank" rel="noopener nofollow noreferrer">https://openui5.org/ui5con/faq.html</A>, including how to attend, sponsor, or propose a topic for a session.</P><P>For links to design and development tools and technology, have a look at the <A href="https://pages.community.sap.com/topics/fiori" target="_blank" rel="noopener noreferrer">SAP Fiori topic page</A> in the SAP Community, or go directly to these pages:</P><UL><LI><A href="https://www.sap.com/design-system/?external" target="_blank" rel="noopener noreferrer">SAP Design System</A>.</LI><LI><A href="https://community.sap.com/topics/fiori-tools" target="_blank">SAP Fiori tools</A>.</LI><LI><A href="https://pages.community.sap.com/topics/ui5" target="_blank" rel="noopener noreferrer">SAPUI5</A>.</LI><LI><A href="https://community.sap.com/topics/fiori-elements" target="_blank">SAP Fiori elements</A>.</LI><LI><A href="https://developers.sap.com/topics/mobile.html" target="_blank" rel="noopener noreferrer">SAP Mobile technologies</A>.</LI></UL><P> </P><H1 id="toc-hId--1104200540">Final words</H1><P>As you can see from all seven posts in the series, we continue to progress rapidly with the user experience of our product portfolio, especially with regards to AI-assistance.</P><P>Part 1 of the series lists all the parts, and links to those parts that have already been published:</P><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-ux-q1-2026-update-part-1-ai-joule-sap-build-work-zone-sap-mobile-start/ba-p/14312110" target="_blank">SAP UX Q1/2026 Update – Part 1: AI, Joule, SAP Build Work Zone, SAP Mobile Start</A>.</LI></UL><P>Do keep posting your experiences and recommendations yourself in the SAP Community, with the SAP Fiori and/or the User Experience tag! In case you are wondering how to get a list of the most recent blog posts on SAP Fiori and User Experience in our new SAP Community, use these links:</P><UL><LI><A href="https://community.sap.com/t5/c-khhcw49343/SAP+Fiori/pd-p/73554900100700000977" target="_blank">Latest blog posts on SAP Fiori in the SAP Community</A>.</LI><LI><A href="https://community.sap.com/t5/c-khhcw49343/User+Experience/pd-p/4616d815-f39e-45c8-b13b-5a2d6679778f" target="_blank">Latest blog posts on User Experience in the SAP Community</A>.</LI></UL><P>For general information on design at SAP and SAP Fiori, check out:</P><UL><LI><A href="http://www.sap.com/design" target="_blank" rel="noopener noreferrer">www.sap.com/design</A>.</LI><LI><A href="http://www.sap.com/fiori" target="_blank" rel="noopener noreferrer">www.sap.com/fiori</A>.</LI><LI><A href="https://pages.community.sap.com/topics/fiori" target="_blank" rel="noopener noreferrer">SAP Community: SAP Fiori topic page</A><SPAN>.</SPAN></LI></UL>2026-03-23T09:53:54.363000+01:00https://community.sap.com/t5/frontend-ui5-sap-fiori-blog-posts/removal-of-legacy-sap-ui-webc-web-component-ui-libraries-from-sapui5/ba-p/14358564Removal of legacy sap.ui.webc.* Web Component UI libraries from SAPUI5/OpenUI5 1.147.0 onwards2026-03-26T09:26:57.814000+01:00pmuessighttps://community.sap.com/t5/user/viewprofilepage/user-id/42075<H1 id="toc-hId-1663391809">Saying Goodbye to <CODE>sap.ui.webc.*</CODE> — How SAPUI5/OpenUI5 Now Integrates Web Components Natively</H1><P>If you've used the <CODE>sap.ui.webc.main</CODE>, <CODE>sap.ui.webc.fiori</CODE>, or <CODE>sap.ui.webc.common</CODE> libraries in a SAPUI5 or OpenUI5 application, this post is for you. <STRONG>These libraries will be removed in version 1.147.0</STRONG>, one release before the next long-term support (LTS) version 1.148. They will not be available in the 1.148 LTS or any version after.</P><P>Here's what happened, what's changing, and what you should do.</P><H2 id="toc-hId-1595961023">The Short Version</H2><P>The <CODE>sap.ui.webc.*</CODE> libraries were an experimental attempt to bring <A href="https://sap.github.io/ui5-webcomponents/" target="_blank" rel="noopener nofollow noreferrer">UI5 Web Components</A> into the SAPUI5 programming model. They were introduced in version 1.92 (2021) as experimental, deprecated in version 1.120 (2023), and <STRONG>will be removed in version 1.147.0</STRONG>. They never left experimental status.</P><P>The new solution is a much better approach: <STRONG>native Web Components integration</STRONG> built directly into <CODE>sap.ui.core</CODE>, available since version 1.138. Instead of frozen wrapper libraries, you now consume Web Components from npm as first-class citizens of the framework.</P><H2 id="toc-hId-1399447518">What Were the <CODE>sap.ui.webc.*</CODE> Libraries?</H2><P>The idea was straightforward: take each UI5 Web Component (like <CODE>ui5-button</CODE>, <CODE>ui5-shellbar</CODE>, <CODE>ui5-table</CODE>) and wrap it as a classic SAPUI5 <CODE>ManagedObject</CODE>-based control — complete with properties, aggregations, events, and data binding support.</P><P>Three libraries made up this approach:</P><P>Library Purpose</P><TABLE><TBODY><TR><TD><CODE>sap.ui.webc.common</CODE></TD><TD>Base infrastructure, bundled the UI5 Web Components runtime</TD></TR><TR><TD><CODE>sap.ui.webc.main</CODE></TD><TD>~70 controls wrapping <CODE>@ui5/webcomponents</CODE> (Button, Input, Table, Dialog, ...)</TD></TR><TR><TD><CODE>sap.ui.webc.fiori</CODE></TD><TD>~30 controls wrapping <CODE>@ui5/webcomponents-fiori</CODE> (ShellBar, Wizard, Timeline, ...)</TD></TR></TBODY></TABLE><P>This "retrofit" approach worked, but it came with significant drawbacks:</P><UL><LI><STRONG>Frozen dependency.</STRONG> The libraries bundled <CODE>@ui5/webcomponents</CODE> v1.18.0 as static thirdparty files. When the UI5 Web Components project shipped v2.x with major improvements, the <CODE>sap.ui.webc.*</CODE> libraries stayed on v1.18 — forever.</LI><LI><STRONG>Maintenance overhead.</STRONG> Every new Web Component or API change required manually updating the wrapper code and re-bundling the thirdparty files. This didn't scale.</LI><LI><STRONG>Experimental lock.</STRONG> Because of these constraints, the libraries never graduated beyond <CODE>@experimental</CODE> status. They were always flagged with: <EM>"This API is experimental and might change significantly."</EM></LI></UL><H2 id="toc-hId-1202934013">Why They Were Deprecated</H2><P>In version 1.120 — the previous LTS release — all three libraries were marked <CODE>@deprecated</CODE> with the message:</P><BLOCKQUOTE><P><EM>"This Web Components consumption model has been discarded. An alternative consumption model is planned for the future."</EM></P></BLOCKQUOTE><P>That alternative has arrived a while ago.</P><H2 id="toc-hId-1006420508">The Better Approach: <CODE>sap.ui.core.webc.WebComponent</CODE></H2><P>Since version 1.138, SAPUI5 includes a new public base class — <CODE>sap.ui.core.webc.WebComponent</CODE> — that lives directly in <CODE>sap.ui.core</CODE>. This is not another wrapper library. It's a framework-level integration point.</P><P>Here's what's different:</P><P><STRONG>1. Web Components come from npm, not from frozen bundles.</STRONG></P><P>Instead of shipping a static copy of <CODE>@ui5/webcomponents</CODE>, the new approach uses <A href="https://www.npmjs.com/package/ui5-tooling-modules" target="_blank" rel="noopener nofollow noreferrer">ui5-tooling-modules</A> to consume Web Components directly from npm packages at build time. This means your application stays on current Web Component versions — today v2.x — rather than being locked to a frozen v1.18 copy.</P><P><STRONG>2. Integration is at the framework level.</STRONG></P><P>The <CODE>WebComponent</CODE> base class in <CODE>sap.ui.core</CODE> handles property propagation, aggregation-to-slot mapping, event forwarding, and rendering integration generically. Individual Web Component wrappers are thin — generated metadata, not hand-maintained control code.</P><P><STRONG>3. The framework is already using it internally.</STRONG></P><P>The new integration approach is already used within the framework itself — for example, the Shell and Enterprise Search in the <CODE>sap.f</CODE> library consume Web Components through this mechanism. While these specific integrations are currently private/restricted APIs, they validate that the approach works at scale in production scenarios. Public Web Component-based controls built on <CODE>sap.ui.core.webc.WebComponent</CODE> will follow.</P><P><STRONG>4. It's public API.</STRONG></P><P>Unlike the <CODE>sap.ui.webc.*</CODE> libraries which stayed experimental for their entire lifecycle, <CODE>sap.ui.core.webc.WebComponent</CODE> is a public, stable API since 1.138.</P><H2 id="toc-hId-809907003">What You Should Do</H2><P><STRONG>If you never used <CODE>sap.ui.webc.*</CODE>:</STRONG> Nothing changes for you. If you want to use Web Components in your SAPUI5 app going forward, read the <A href="https://sdk.openui5.org/#/topic/1c80793df5bb424091954697fc0b2828" target="_blank" rel="noopener nofollow noreferrer">Using Web Components</A> documentation.</P><P><STRONG>If you used <CODE>sap.ui.webc.*</CODE> in a prototype or experiment:</STRONG> Since these libraries were always experimental, now is the time to move to the new approach. The controls you were using (like <CODE>sap.ui.webc.main.Button</CODE> or <CODE>sap.ui.webc.fiori.ShellBar</CODE>) have no 1:1 migration path because the consumption model changed fundamentally. However, the underlying Web Components are the same — and better, since you now get v2.x instead of v1.18.</P><P><STRONG>If you used <CODE>sap.ui.webc.*</CODE> in a productive application despite the experimental status:</STRONG> The libraries will be removed in version 1.147.0. We recommend starting the migration now. The <A href="https://sdk.openui5.org/#/topic/1c80793df5bb424091954697fc0b2828" target="_blank" rel="noopener nofollow noreferrer">Using Web Components</A> guide is your starting point.</P><P><STRONG>If you're on the 1.120 LTS and planning to upgrade to the next LTS:</STRONG> The previous LTS (1.120) still ships the deprecated <CODE>sap.ui.webc.*</CODE> libraries. The next LTS (1.148) will not — they are removed one version earlier in 1.147. If your application depends on these libraries, you must migrate before upgrading to 1.148 LTS.</P><H2 id="toc-hId-613393498">Timeline</H2><P>Version Event</P><TABLE><TBODY><TR><TD><STRONG>1.92</STRONG> (2021)</TD><TD><CODE>sap.ui.webc.*</CODE> introduced as <STRONG>experimental</STRONG></TD></TR><TR><TD><STRONG>1.120</STRONG> (2023)</TD><TD><CODE>sap.ui.webc.*</CODE> <STRONG>deprecated</STRONG> — previous LTS</TD></TR><TR><TD><STRONG>1.138</STRONG> (2025)</TD><TD><CODE>sap.ui.core.webc.WebComponent</CODE> introduced as <STRONG>public API</STRONG></TD></TR><TR><TD><STRONG>1.147</STRONG></TD><TD><CODE>sap.ui.webc.*</CODE> libraries <STRONG>removed</STRONG></TD></TR><TR><TD><STRONG>1.148</STRONG></TD><TD><STRONG>Next LTS release</STRONG> — <CODE>sap.ui.webc.*</CODE> not available</TD></TR></TBODY></TABLE><H2 id="toc-hId-416879993">Summary</H2><P>The <CODE>sap.ui.webc.*</CODE> libraries were an early experiment that taught us a lot about what Web Components integration in SAPUI5 should look like. The answer turned out to be: don't bundle frozen copies — integrate at the framework level and let developers consume Web Components from the ecosystem directly.</P><P>That's exactly what the new approach does, and it's available today.</P><P><STRONG>Next step:</STRONG> <A href="https://sdk.openui5.org/#/topic/1c80793df5bb424091954697fc0b2828" target="_blank" rel="noopener nofollow noreferrer">Using Web Components in SAPUI5</A></P>2026-03-26T09:26:57.814000+01:00https://community.sap.com/t5/technology-blog-posts-by-members/bringing-ai-directly-into-sapui5-controls-ai-ui5-library/ba-p/14363248Bringing AI Directly Into SAPUI5 Controls - AI UI5 Library2026-04-01T07:23:19.699000+02:00WouterLemairehttps://community.sap.com/t5/user/viewprofilepage/user-id/9863<P>A lot of AI work in the SAP space focuses on agents, assistants, and orchestration. This post is about something smaller in scope: bringing AI directly into SAPUI5 as reusable controls, close to where users interact with data every day.</P><P>Users frequently work with text fields, writing descriptions, filling in notes, composing messages. Tasks like improving the tone of a text, fixing spelling mistakes, or translating a field value are small, well-defined, and a good fit for what LLMs do well. This post shares an experiment in packaging that kind of capability into a UI5 control library.</P><H2 id="toc-hId-1793246153">The idea: AI as reusable UI5 controls</H2><P>The library (be.wl.ai) provides a set of AI-powered UI5 controls that can be dropped into any XML view. A consuming app developer doesn’t need to know anything about AI Core or set up any AI infrastructure, they reference the library, add a control and bind it to a model property:</P><P><TextArea value="{/description}" /></P><P><ai:AIPolishButton text="Polish" value="{/description}" /></P><P>The TextArea and the AI button are both bound to the same model property. When the user accepts the AI result, it flows back into the model and the TextArea updates automatically, standard UI5 two-way data binding, nothing custom required.</P><H2 id="toc-hId-1596732648">What’s in the library</H2><P>The library provides 11 controls covering the most common AI text operations:</P><P><A href="https://github.com/lemaiwo/ui5-ai-features" target="_blank" rel="noopener nofollow noreferrer">https://github.com/lemaiwo/ui5-ai-features</A></P><P><STRONG>Text transformation (Accept/Reject dialog):</STRONG></P><UL><LI><STRONG>AIPolishButton</STRONG> — improves grammar, clarity, and professionalism</LI><LI><STRONG>AIGenerateButton</STRONG> — generates text from a short description</LI><LI><STRONG>AISpellCheckButton</STRONG> — corrects errors and shows a summary of changes</LI><LI><STRONG>AIToneButton</STRONG> — rewrites text in a different tone (formal, casual, persuasive, etc.)</LI><LI><STRONG>AITranslateButton</STRONG> — translates into 12 languages via a dropdown menu</LI></UL><P><STRONG>Analysis (read-only results):</STRONG></P><UL><LI><STRONG>AISummarizeButton</STRONG> — produces a concise summary</LI><LI><STRONG>AIExtractKeywordsButton</STRONG> — extracts keywords as tokens with copy-to-clipboard</LI><LI><STRONG>AICompareTexts</STRONG> — compares two texts and shows differences in HTML</LI><LI><STRONG>AISentimentIndicator</STRONG> — shows a positive/neutral/negative sentiment badge</LI></UL><P><STRONG>Inline assistance:</STRONG></P><UL><LI><STRONG>AIInputSuggestion</STRONG> — opens a popover with an AI-suggested improvement</LI><LI><STRONG>AIAutoComplete</STRONG> — completes partial text inline</LI></UL><P>Every control uses standard UI5 two-way data binding through a value property. Bind it to the same model property as your input field, and the AI result flows back automatically.</P><H2 id="toc-hId-1400219143">Architecture: simple on purpose</H2><P>The controls connect to a CAP backend service that wraps SAP AI Core’s Orchestration Service. The library creates a single shared OData model internally, app developers never see it.</P><P>The key design decision: <STRONG>the controls own their connection to the AI service</STRONG>. The consuming app doesn’t need to configure a model, set up a destination or know anything about AI Core. Import the library, use the controls, done.</P><P>Under the hood, all button controls extend a shared AIBaseButton base class that handles the OData call, dialog lifecycle, busy indicators, and accept/reject flow. Building a new AI control takes about 50 lines of code, just override the prompt, icon, and event name.</P><H2 id="toc-hId-1203705638">Design decisions worth noting</H2><P>A few choices shaped how this library ended up, and they’re worth explaining for anyone considering a similar approach.</P><P><STRONG>The controls own their AI connection.</STRONG> Rather than requiring the consuming app to configure a model or destination, the library manages its own OData connection to the CAP backend internally. This keeps the integration surface small, an app developer just binds a value property, the same way they would with any other UI5 control.</P><P><STRONG>Standard UI5 patterns throughout.</STRONG> The controls use properties, events, and data binding exactly as UI5 developers would expect. There’s no custom state management or framework-specific logic. This makes the controls easier to understand, debug, and extend.</P><P><STRONG>Prompts are exposed as properties.</STRONG> Every control has a prompt property that overrides the default. This makes it straightforward to adapt a control’s behaviour for a specific domain or use case without forking the library.</P><P><STRONG>No SAP-specific beta features.</STRONG> Everything here runs on generally available SAP technology, UI5, CAP, and AI Core Orchestration Service. There’s no dependency on preview APIs or experimental tooling.</P><H2 id="toc-hId-1007192133">Current status</H2><P>This is a first version and a proof of concept of what’s possible. It works locally with cds watch and the controls are fully functional. The library is structured for deployment to SAP BTP (MTA with HTML5 repo host), but it hasn’t been tested deployed yet.</P><P>The code is intentionally kept simple. There’s no streaming, no conversation history, no RAG. Just a text in, text out pattern, which covers a surprising number of real use cases.</P><H2 id="toc-hId-810678628">Try it yourself</H2><H3 id="toc-hId-743247842">Prerequisites</H3><UL><LI>Node.js 20+</LI><LI>An SAP AI Core instance (extended plan) with access to the Orchestration Service</LI><LI>A deployment of a model like GPT-4o through SAP AI Core</LI></UL><H3 id="toc-hId-546734337">Running locally</H3><P>The AI controls call SAP AI Core’s Orchestration Service on the backend. To run this locally, you need to use the <STRONG>hybrid approach</STRONG> — your CAP server runs on your machine but binds to a real AI Core service instance on SAP BTP.</P><OL><LI>Clone the repository:</LI></OL><pre class="lia-code-sample language-abap"><code>git clone https://github.com/lemaiwo/ui5-ai-features.git
cd ui5-ai-features
npm install</code></pre><OL><LI>Log in to your Cloud Foundry environment:</LI></OL><pre class="lia-code-sample language-abap"><code>cf login</code></pre><OL><LI>Bind to your AI Core instance using the hybrid profile:</LI></OL><pre class="lia-code-sample language-abap"><code>npm run bind</code></pre><OL><LI>Start the dev server with the hybrid profile:</LI></OL><pre class="lia-code-sample language-abap"><code>npm run watch-hybrid</code></pre><OL><LI>Open the app at the URL shown in the terminal:</LI></OL><P><A href="http://localhost:4004/be.wl.ai.aidemo/index.html" target="_blank" rel="noopener nofollow noreferrer">http://localhost:4004/be.wl.ai.aidemo/index.html</A></P><H3 id="toc-hId-350220832">Using the library in your own app</H3><P>The library lives in app/ai-lib and the demo app in app/aidemo. To use the controls in your own app, add the library as a dependency and start using them in your XML views:</P><pre class="lia-code-sample language-abap"><code><mvc:View xmlns:ai="be.wl.ai">
<TextArea value="{/notes}" />
<ai:AIPolishButton text="Polish" value="{/notes}" />
<ai:AITranslateButton text="Translate" value="{/notes}" />
<ai:AISpellCheckButton text="Spell Check" value="{/notes}" />
</mvc:View></code></pre><P>The controls use two-way data binding. Bind both the TextArea and the AI control to the same model property, when the user accepts the AI result, the TextArea updates automatically.</P><H2 id="toc-hId-24624608">Takeaways</H2><P>This started as an experiment to see how much AI functionality could be packaged into reusable UI5 controls without requiring app developers to understand the AI layer. The answer is: quite a lot, with a relatively small amount of code.</P><P>The text in, text out pattern is simpler than agent-based approaches, but it fits a wide range of real use cases that users encounter daily. It also sits comfortably alongside agent and MCP work, both approaches address different parts of the problem.</P><P>The code is available if you want to explore, fork, or adapt it. Feedback and ideas are welcome.</P><H1 id="toc-hId-468768467">Result</H1><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="WouterLemaire_0-1775020935981.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391797i05EDD9EEF7271D7F/image-size/medium?v=v2&px=400" role="button" title="WouterLemaire_0-1775020935981.png" alt="WouterLemaire_0-1775020935981.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="WouterLemaire_1-1775020948508.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391798i8FFA08B4B85DBDC5/image-size/medium?v=v2&px=400" role="button" title="WouterLemaire_1-1775020948508.png" alt="WouterLemaire_1-1775020948508.png" /></span></P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="WouterLemaire_2-1775020956329.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391799i4D8D2C3082B6C848/image-size/medium?v=v2&px=400" role="button" title="WouterLemaire_2-1775020956329.png" alt="WouterLemaire_2-1775020956329.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="WouterLemaire_3-1775020962236.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391800i57D1F731D323AE20/image-size/medium?v=v2&px=400" role="button" title="WouterLemaire_3-1775020962236.jpeg" alt="WouterLemaire_3-1775020962236.jpeg" /></span></P><P> </P><P> </P>2026-04-01T07:23:19.699000+02:00https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-ui5-plugins-for-claude-ai-powered-development-for-sapui5-and/ba-p/14362731Introducing UI5 Plugins for Claude: AI-Powered Development for SAPUI5 and OpenUI52026-04-01T08:43:13.601000+02:00FlorianVogthttps://community.sap.com/t5/user/viewprofilepage/user-id/216201<H1 id="toc-hId-1664138410">Introducing UI5 Plugins for Claude: AI-Powered Development for SAPUI5 and OpenUI5</H1><P>We're introducing <STRONG>UI5 plugins for Claude</STRONG>, an open-source collection of plugins for Claude Code. These plugins are designed to enhance UI5 development workflows with AI assistance.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="FlorianVogt_0-1774962551859.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391605i640108A5B32DAE88/image-size/large?v=v2&px=999" role="button" title="FlorianVogt_0-1774962551859.png" alt="FlorianVogt_0-1774962551859.png" /></span></P><H2 id="toc-hId-1596707624">What Are Claude Code Plugins?</H2><P><A href="https://code.claude.com/docs/" target="_blank" rel="noopener nofollow noreferrer">Claude Code</A> is Anthropic's AI-powered CLI for software development. Its plugin system lets domain experts extend Claude's built-in capabilities with specialized knowledge, tools, and skills for a specific technology. With plugins, Claude Code becomes aware of framework-specific conventions, APIs, and best practices. This means developers get more accurate, context-aware assistance without having to explain the fundamentals every time.</P><H2 id="toc-hId-1400194119">Why We Built This</H2><P>The UI5 framework has a rich but specialized programming model. Developers, especially those new to UI5 or returning after a break, often spend significant time looking up the correct patterns for class definitions, module loading, TypeScript typing, and toolchain configuration. AI assistance can save hours in these situations, but only if the AI has accurate, curated knowledge of the framework.</P><P>Rather than relying on the LLM's general training data, which can be outdated or incomplete for framework details, these plugins embed current, maintained guidelines directly into the development workflow. The result is that Claude Code provides UI5-accurate suggestions from Day One, so you don't have to paste documentation into every conversation.</P><P>Last year, we published the <A href="https://github.com/UI5/mcp-server" target="_blank" rel="noopener nofollow noreferrer">UI5 MCP server</A> described in <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/give-your-ai-agent-some-tools-introducing-the-ui5-mcp-server/bc-p/14361822" target="_blank">Give Your AI Agent Some Tools: Introducing the UI5 MCP Server</A>. The introduction of <A href="https://agentskills.io/" target="_blank" rel="noopener nofollow noreferrer">agent skills</A> over the last year makes some tasks easier to complete compared to using only the UI5 MCP server. MCP servers aren't going away; this just introduces a new way to distribute tasks between MCP servers or skills. The choice depends on the task: Skills work well for tasks described in free text, while MCP servers offer better support for tasks that require precise input and output.</P><H2 id="toc-hId-1203680614">What We Are Releasing</H2><P>The initial release ships two plugins:</P><H3 id="toc-hId-1136249828">1. UI5 Plugin — Your UI5 Development Companion</H3><P>The <A href="https://claude.com/plugins/ui5" target="_self" rel="nofollow noopener noreferrer">UI5 plugin</A> equips Claude Code with deep knowledge of the SAPUI5 and OpenUI5 ecosystem. It helps you with the following tasks:</P><UL><LI><STRONG>Create new UI5 projects</STRONG>: Create scaffolded project structures based on best practices without any manual setup.</LI><LI><STRONG>Detect and fix UI5-specific errors</STRONG>: Claude understands UI5 linting rules and applies fixes based on the official guidelines.</LI><LI><STRONG>Access UI5 API documentation</STRONG>: Get accurate, framework-aware answers about controls, modules, events, and APIs instead of generic JavaScript suggestions.</LI></UL><P>Technically, the plugin is a wrapper around the UI5 MCP server. Install it with a single command:</P><PRE><CODE>claude plugin install ui5@claude-plugins-official</CODE></PRE><P>Or from within Claude Code:</P><PRE><CODE>/plugin install ui5@claude-plugins-official</CODE></PRE><H3 id="toc-hId-939736323">2. UI5 TypeScript Conversion plugin — Migrate to TypeScript with Confidence</H3><P>Migrating a JavaScript UI5 project to TypeScript can be tricky. Generic AI tools often handle the required transformations incorrectly. These transformations are necessary for the UI5 class system, the <CODE>sap.ui.define</CODE> module loader, runtime-generated getter and setter methods on controls, and library-specific patterns. The <A href="https://claude.com/plugins/ui5-typescript-conversion" target="_self" rel="nofollow noopener noreferrer">UI5 TypeScript Conversion plugin</A> provides Claude Code with a step-by-step conversion playbook.</P><P>Install it with:</P><PRE><CODE>claude plugin install ui5-typescript-conversion@claude-plugins-official</CODE></PRE><H2 id="toc-hId-614140099">Get Started</H2><OL><LI>Install <A href="https://code.claude.com/docs/" target="_blank" rel="noopener nofollow noreferrer">Claude Code</A>.</LI><LI>Install one or both plugins as shown above.</LI><LI>Start coding. For example, you can ask Claude Code to create a UI5 project, run UI5 linter, explain an API, or start a TypeScript migration.</LI></OL><P>The source code for both plugins is available on GitHub at <A href="https://github.com/UI5/plugins-claude" target="_blank" rel="noopener nofollow noreferrer">UI5/plugins-claude</A> under the Apache 2.0 license. We welcome contributions, bug reports, and feature requests via GitHub Issues.</P><P>You can also join the conversation in the <A href="https://openui5.slack.com/archives/C0ALUUXQN9K" target="_blank" rel="noopener nofollow noreferrer">#ai</A> channel of the <A href="https://ui5-slack-invite.cfapps.eu10.hana.ondemand.com/" target="_blank" rel="noopener nofollow noreferrer">OpenUI5 Community Slack</A> or ask questions on Stack Overflow using the <A href="https://stackoverflow.com/questions/tagged/ui5-plugins-claude" target="_blank" rel="noopener nofollow noreferrer"><CODE>ui5-plugins-claude</CODE></A> tag.</P>2026-04-01T08:43:13.601000+02:00https://community.sap.com/t5/frontend-ui5-sap-fiori-blog-posts/mastering-sapui5-custom-filter-variants-without-a-backend-table/ba-p/14366439Mastering SAPUI5 custom Filter Variants Without a Backend Table2026-04-06T12:16:46.286000+02:00SBedrehttps://community.sap.com/t5/user/viewprofilepage/user-id/1610167<P><STRONG>Mastering SAPUI5 Filter Variants Without a Backend Table</STRONG></P><P>Many SAPUI5 developers assume that <STRONG>filter variants require a backend table</STRONG>. You might have even thought: “How can I save user filter preferences without touching a database?”</P><P>Here’s the good news: <STRONG>you absolutely can</STRONG>, and it’s cleaner, faster, and fully Fiori-compliant. Using <STRONG>SmartVariantManagement (SVM)</STRONG> and a <STRONG>FilterBar</STRONG>, you can build full variant management <STRONG>entirely client-side</STRONG>, while supporting complex controls like MultiInput, MultiComboBox, and DateRangeSelection.</P><P>In this blog, we’ll walk through a <STRONG>real-world implementation with custom development in UI.</STRONG></P><P><STRONG>1️</STRONG><STRONG>⃣ Why Backend Tables Are Not Always Needed</STRONG></P><P>Most SAP examples integrate variants with <STRONG>OData services</STRONG> or <STRONG>SmartTables</STRONG>, which gives the impression that <STRONG>server-side storage is required</STRONG>.</P><P>But here’s the truth:</P><UL><LI><STRONG>SmartVariantManagement</STRONG> can store variants for standalone apps.</LI><LI>If your app runs in <STRONG>Launchpad</STRONG>, variants are stored in the <STRONG>personalization service</STRONG>.</LI><LI>The only requirement is to connect your FilterBar to SVM <STRONG>programmatically</STRONG>.</LI></UL><P><STRONG>2️</STRONG><STRONG>⃣ The View Setup</STRONG></P><P>Here’s a clean XML setup with <STRONG>SVM</STRONG> and a <STRONG>FilterBar</STRONG>:</P><pre class="lia-code-sample language-markup"><code><smartvariants:SmartVariantManagement
id="svm"
showExecuteOnSelection="true"
/>
<fb:FilterBar
id="filterbarList"
useToolbar="false"
search=".onSearch"
persistencyKey="evaluationFilterBar"
showFilterConfiguration="true"
afterVariantLoad=".onAfterVariantLoad"
/></code></pre><P><STRONG>Key Points:</STRONG></P><UL><LI>showExecuteOnSelection="true" ensures users can <STRONG>auto-execute searches</STRONG> when a variant is selected.</LI><LI>persistencyKey allows local persistence even <STRONG>without backend tables</STRONG>.</LI><LI>The FilterBar does <STRONG>not automatically connect</STRONG> to SVM; we handle that in the controller.</LI></UL><P><STRONG>3️</STRONG><STRONG>⃣ Wiring FilterBar to SVM in the Controller</STRONG></P><P><STRONG>3.1 Register Fetch and Apply Functions</STRONG></P><pre class="lia-code-sample language-javascript"><code>this._oFilterBar = this.byId("filterbarList");
this._oSmartVariantManagement = this.byId("svm");
this._oFilterBar.registerFetchData(this._fetchVariantData.bind(this));
this._oFilterBar.registerApplyData(this._applyVariantData.bind(this));
this._oFilterBar.attachAfterVariantLoad(this._onAfterVariantLoad.bind(this);</code></pre><UL><LI>_fetchVariantData() extracts <STRONG>all filter values</STRONG> into JSON.</LI><LI>_applyVariantData() restores values when a variant is selected.</LI><LI>afterVariantLoad ensures <STRONG>auto-search</STRONG> or other post-load logic runs.</LI></UL><P><STRONG>3.2 Add FilterBar as Personalizable Control</STRONG></P><pre class="lia-code-sample language-javascript"><code>const oPersInfo = new PersonalizableInfo({
type: "filterBar",
keyName: "persistencyKey",
dataSource: "",
control: this._oFilterBar
});
this._oSmartVariantManagement.addPersonalizableControl(oPersInfo);</code></pre><UL><LI>PersonalizableInfo registers the FilterBar with SVM, enabling <STRONG>full variant management</STRONG>, including <STRONG>Execute on Selection</STRONG>.</LI></UL><P><STRONG>3.3 Initialize SmartVariantManagement</STRONG></P><pre class="lia-code-sample language-javascript"><code>this._oSmartVariantManagement.initialise(function () {}, this._oFilterBar);</code></pre><UL><LI>Establishes the connection between <STRONG>SVM</STRONG> and <STRONG>FilterBar</STRONG>.</LI><LI>Variants are now <STRONG>fully functional</STRONG>, even without any backend storage.</LI></UL><P><STRONG>4️</STRONG><STRONG>⃣ Handling Complex Filter Controls</STRONG></P><P><STRONG>Fetch Variant Data : Explicitly fetches all tokens from <CODE>MultiInput</CODE> controls so multiple values are captured per filter.</STRONG></P><pre class="lia-code-sample language-javascript"><code>_fetchVariantData() {
const oData = {};
this._oFilterBar.getAllFilterItems().forEach(item => {
const oControl = item.getControl();
if (!oControl) return;
if (oControl.isA("sap.m.MultiInput")) {
oData[item.getName()] = oControl.getTokens().map(t => t.getKey() || t.getText());
}
if (oControl.isA("sap.m.DateRangeSelection")) {
oData[item.getName()] = {
from: oControl.getDateValue(),
to: oControl.getSecondDateValue()
};
}
if (oControl.isA("sap.m.MultiComboBox")) {
oData[item.getName()] = oControl.getSelectedKeys();
}
});
return oData;
}</code></pre><P><STRONG>Apply Variant Data : Ensures all stored tokens are re-applied, supporting multi-value filter selection.</STRONG></P><pre class="lia-code-sample language-javascript"><code>_applyVariantData(oData) {
if (!oData) return;
this._oFilterBar.getAllFilterItems().forEach(item => {
const oControl = item.getControl();
const vValue = oData[item.getName()];
if (!oControl) return;
if (oControl.isA("sap.m.MultiInput")) {
oControl.removeAllTokens();
if (Array.isArray(vValue)) {
vValue.forEach(val => oControl.addToken(new sap.m.Token({ key: val, text: val })));
}
}
if (oControl.isA("sap.m.DateRangeSelection")) {
oControl.setDateValue(vValue?.from || null);
oControl.setSecondDateValue(vValue?.to || null);
}
if (oControl.isA("sap.m.MultiComboBox")) {
oControl.setSelectedKeys(vValue || []);
}
});
// Trigger search automatically
this.onSearch();
}</code></pre><UL><LI>These functions <STRONG>serialize and restore all filter control values</STRONG>, making the variants robust and accurate.</LI></UL><P><STRONG>5️</STRONG><STRONG>⃣ How It Works (Visual Diagram)</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="custom-varinat-flow.png" style="width: 269px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394203i10830E6FA2914D1A/image-size/medium?v=v2&px=400" role="button" title="custom-varinat-flow.png" alt="custom-varinat-flow.png" /></span></P><P><STRONG>Flow Explanation:</STRONG></P><OL><LI><STRONG>FilterBar</STRONG> registers fetch/apply logic for all controls.</LI><LI><STRONG>PersonalizableInfo</STRONG> connects FilterBar to SVM.</LI><LI>Variants are stored in personalization.</LI><LI>Users can <STRONG>save, load, and auto-execute</STRONG> variants seamlessly.</LI></OL><P><STRONG>6️</STRONG><STRONG>⃣ Key Benefits</STRONG></P><UL><LI> Fully functional variant management <STRONG>without a backend table</STRONG></LI><LI>Supports complex controls: MultiInput, MultiComboBox, DateRangeSelection</LI><LI>upports complex controls and <STRONG>multi-value filters via tokens</STRONG></LI><LI>Enables <STRONG>Execute on Selection</STRONG></LI><LI>Works in <STRONG>standalone apps</STRONG> or <STRONG>Fiori Launchpad</STRONG></LI><LI>Easy to extend for additional custom controls</LI></UL><P><STRONG>7️</STRONG><STRONG>⃣ Key Takeaways</STRONG></P><OL><LI>FilterBar alone is not enough; manual SVM wiring is required.</LI><LI>PersonalizableInfo + addPersonalizableControl() + initialise() connects everything.</LI><LI>Added: <CODE>Custom fetch/apply functions handle complex controls and **tokenized multi-value filters**.</CODE></LI><LI>Custom fetch/apply functions handle complex controls.</LI><LI>Variants can be fully stored <STRONG>client-side</STRONG>, making backend persistence optional.</LI></OL><H3 id="toc-hId-1922420137"><SPAN><STRONG>Bonus: User-Specific Variants</STRONG></SPAN></H3><P>One surprising feature is that these variants <STRONG>respect user profiles</STRONG> automatically. Even though the variants are stored client-side or in FLP personalization, each user sees their <STRONG>own saved variants</STRONG>. This means you can have multiple users using the same app, each with their own filter preferences, without any backend table or custom storage logic.</P><P><STRONG>Key points:</STRONG></P><UL><LI>Variants are automatically scoped per user in Fiori Launchpad or browser storage.</LI><LI>No extra coding is required to separate user preferences.</LI><LI>Works seamlessly with Execute on Selection and all complex controls.</LI></UL><P>With this approach, you give users a <STRONG>robust, professional, Fiori-compliant variant experience</STRONG>—without the overhead of backend tables.</P>2026-04-06T12:16:46.286000+02:00https://community.sap.com/t5/technology-blog-posts-by-sap/more-power-new-name-the-ui-flexibility-service-explained/ba-p/14367188More Power, New Name: The UI Flexibility Service Explained2026-04-07T09:27:16.370000+02:00OliverGraeffhttps://community.sap.com/t5/user/viewprofilepage/user-id/4124<H1 id="toc-hId-1664281761"><STRONG>SAPUI5 flexibility for adapting standard SAP apps</STRONG></H1><P>SAPUI5 is SAP’s strategic Web framework for SAP Fiori. SAPUI5 flexibility allows developers, key users, and end users to adapt standard apps with simple drag-and-drop tools. Discover all the capabilities here: <SPAN><A href="https://help.sap.com/docs/UI5_FLEXIBILITY/430e2c1a4ff241bc8162df4bf51e0730/e36d19b3d24f47199a9a82d3faa508c3.html" target="_blank" rel="noopener noreferrer">SAPUI5 Flexibility - All You Need to Know</A></SPAN>.</P><P> </P><H1 id="toc-hId-1467768256"><STRONG>Key user adaptation</STRONG></H1><P>Key user adaptation is built into SAP Fiori Launchpad / SAP Build Work Zone and is included commercially as part of the respective product. Outside these products, the same capabilities are available as a dedicated service, <STRONG>UI5 flexibility for key users,</STRONG> on SAP BTP, enabling key user adaptation for standalone apps, for example, for SAP partners building their own apps. The service is available via BTPEA, BTP Trial, and partner TD&D licenses. See details in the <SPAN><A href="https://discovery-center.cloud.sap/serviceCatalog/ui5-flexibility-for-key-users?region=all" target="_blank" rel="noopener nofollow noreferrer">SAP Discovery Center</A></SPAN>.</P><P> </P><H1 id="toc-hId-1271254751"><STRONG>What's new?</STRONG></H1><P>Some time ago, we added the <SPAN><A href="https://help.sap.com/docs/UI5_FLEXIBILITY/430e2c1a4ff241bc8162df4bf51e0730/20b7fbd1d33644819c58c4c98670dcfb.html?language=en-US" target="_blank" rel="noopener noreferrer">end user personalization</A></SPAN> capability to the UI5 flexibility for key users service. This allows also business users to easily change the UI of standard apps, helping them work more efficiently. This created confusion, as the service name <STRONG>UI5 flexibility for key users </STRONG>no longer reflects the full range of benefits. We therefore decided to rename the service:<BR /><BR /></P><P class="lia-align-center" style="text-align: center;"><FONT size="4"><STRONG>"UI5 flexibility for key users" ➔ "UI flexibility service"</STRONG></FONT></P><P>You will see the name being changed now across all SAP assets, e.g.:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2026-03-30 at 10.26.29.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394111i7521D42D1C68CA9E/image-size/large?v=v2&px=999" role="button" title="Screenshot 2026-03-30 at 10.26.29.png" alt="Screenshot 2026-03-30 at 10.26.29.png" /></span></P><P> </P><P>Apart from the name, nothing changes in the scope or functionality of the <STRONG>UI flexibility service</STRONG>.</P>2026-04-07T09:27:16.370000+02:00https://community.sap.com/t5/abap-blog-posts/deep-entity-handling-in-sap-ui5-using-odata-service/ba-p/14367609Deep Entity Handling in SAP UI5 Using OData Service2026-04-13T07:15:04.408000+02:00Karthik1901https://community.sap.com/t5/user/viewprofilepage/user-id/1915104<UL><LI><FONT size="5"><STRONG>Introduction:</STRONG></FONT></LI></UL><P>A Deep Entity allows you to <STRONG>send and receive hierarchical data (parent + child) in a single request</STRONG>, making your application more efficient, cleaner, and closer to real business scenarios.</P><P>In this blog, we will build a complete end-to-end example of a <STRONG> Deep Entity</STRONG>, covering:</P><UL><LI>Backend implementation using <STRONG>SEGW (ABAP OData)</STRONG></LI><LI>Frontend implementation using <STRONG>SAP UI5</STRONG></LI><LI>Read (Expand) and Create (Deep Insert) operations</LI></UL><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Architecture Overview:</SPAN></SPAN></STRONG></FONT></P><P><SPAN>SAP UI5 App</SPAN><SPAN> </SPAN></P><P><SPAN> ↓</SPAN><SPAN> </SPAN></P><P><SPAN>OData Service (Gateway)</SPAN><SPAN> </SPAN></P><P><SPAN> ↓</SPAN><SPAN> </SPAN></P><P><SPAN>Backend Logic (ABAP)</SPAN><SPAN> </SPAN></P><P><SPAN> ↓</SPAN><SPAN> </SPAN></P><P><SPAN>Database Tables</SPAN><SPAN> </SPAN></P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Backend Implementation (ABAP - OData Service):</SPAN></SPAN></STRONG></FONT></P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class=""><SPAN class=""><SPAN class="">Step 1: Define Entities in SEGW</SPAN></SPAN><SPAN class="">:</SPAN></SPAN></SPAN></STRONG></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_0-1775558622254.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394301i01C1C6568BD249AB/image-size/medium?v=v2&px=400" role="button" title="Unknown21_0-1775558622254.png" alt="Unknown21_0-1775558622254.png" /></span></P><P><SPAN>Create:</SPAN><SPAN> </SPAN></P><UL><LI><SPAN>Header Entity → </SPAN><SPAN>Sales Order</SPAN><SPAN> (VBAK)</SPAN><SPAN> </SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_1-1775558644822.png" style="width: 668px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394302iA1A16909E82415ED/image-dimensions/668x127?v=v2" width="668" height="127" role="button" title="Unknown21_1-1775558644822.png" alt="Unknown21_1-1775558644822.png" /></span></P><UL><LI><SPAN class=""><SPAN class="">Item Entity →<SPAN> </SPAN></SPAN></SPAN><SPAN class=""><SPAN class="">Sales Order Item </SPAN><SPAN class="">(VBAP)</SPAN></SPAN><SPAN class=""> </SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_2-1775558693016.png" style="width: 672px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394303iAB5224DECD4D932A/image-dimensions/672x126?v=v2" width="672" height="126" role="button" title="Unknown21_2-1775558693016.png" alt="Unknown21_2-1775558693016.png" /></span></P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Step 2: Create Association</SPAN></SPAN><SPAN class=""> :</SPAN></STRONG></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_3-1775558738945.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394304iFBC8AC10BDC895FD/image-size/medium?v=v2&px=400" role="button" title="Unknown21_3-1775558738945.png" alt="Unknown21_3-1775558738945.png" /></span></P><UL><LI><SPAN class=""><SPAN class="">Association: Header → Item (1: N</SPAN><SPAN class="">) </SPAN></SPAN><SPAN class=""> </SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_4-1775558779015.png" style="width: 674px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394305i2C86C45B4CCE939B/image-dimensions/674x96?v=v2" width="674" height="96" role="button" title="Unknown21_4-1775558779015.png" alt="Unknown21_4-1775558779015.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_5-1775558798190.png" style="width: 670px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394306iD08342E1B9B04C83/image-dimensions/670x72?v=v2" width="670" height="72" role="button" title="Unknown21_5-1775558798190.png" alt="Unknown21_5-1775558798190.png" /></span></P><UL><LI><SPAN class=""><SPAN class="">Navigation Property:<SPAN> </SPAN></SPAN><SPAN class="">znavigation.</SPAN></SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_6-1775558839716.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394307i38C8DE7F72B64907/image-size/medium?v=v2&px=400" role="button" title="Unknown21_6-1775558839716.png" alt="Unknown21_6-1775558839716.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_7-1775558855092.png" style="width: 681px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394308iE07D05DEDBD93238/image-dimensions/681x80?v=v2" width="681" height="80" role="button" title="Unknown21_7-1775558855092.png" alt="Unknown21_7-1775558855092.png" /></span></P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Step 3: Create </SPAN><SPAN class="">Deep Structure:</SPAN></SPAN></STRONG></FONT><SPAN class=""> </SPAN></P><UL><LI><SPAN class=""><SPAN class=""><SPAN class="">Go<SPAN> </SPAN></SPAN><SPAN class="">To:</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">MPC<SPAN> </SPAN></SPAN><SPAN class="">EXT →</SPAN><SPAN class=""><SPAN> </SPAN></SPAN><SPAN class="">Source Code-Based.</SPAN></SPAN></SPAN><SPAN class=""><SPAN class=""> </SPAN></SPAN></LI><LI><SPAN class=""><SPAN class="">Create Deep Structure.</SPAN></SPAN></LI></UL><P> </P><pre class="lia-code-sample language-abap"><code>class ZCL_ZK_DEEP_ENTITY_MPC_EXT definition
public
inheriting from ZCL_ZK_DEEP_ENTITY_MPC
create public .
public section.
types:
BEGIN OF ty_deep_str,
vbeln TYPE vbeln_va,
erdat TYPE erdat,
ernam TYPE ernam,
auart TYPE auart,
kunnr TYPE kunnr,
znavigation TYPE TABLE OF zcl_zk_deep_entity_mpc_ext=>ts_vbap WITH DEFAULT KEY,
END OF ty_deep_str .
protected section.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_ZK_DEEP_ENTITY_MPC_EXT IMPLEMENTATION.
ENDCLASS. </code></pre><P> </P><P> <FONT size="5"><STRONG><SPAN class=""><SPAN class="">Step 3: Redefine</SPAN><SPAN class=""> </SPAN></SPAN><SPAN class=""><SPAN class="">G</SPAN><SPAN class="">ET_EXPANDED_ENTITY, GET_EXPANDED_ENTITYSET, CREATE_DEEP_ENTITY.</SPAN></SPAN><SPAN class=""><SPAN class=""> </SPAN></SPAN></STRONG></FONT></P><P><SPAN>Go to:</SPAN><SPAN> </SPAN></P><P><SPAN>DPC_EXT Class → Method:</SPAN><SPAN> </SPAN></P><P><STRONG>Method: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY. </STRONG></P><P> </P><pre class="lia-code-sample language-abap"><code>METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.
DATA: ls_deep_str TYPE zcl_zk_deep_entity_mpc_ext=>ty_deep_str,
ls_vbak TYPE zstr_vbak,
lt_vbap TYPE STANDARD TABLE OF zstr_vbap.
DATA lv_vbeln TYPE vbeln_va.
"--------------------------------------------------
" Read key
"--------------------------------------------------
lv_vbeln = VALUE #( it_key_tab[ name = 'Vbeln' ]-value OPTIONAL ).
lv_vbeln = |{ lv_vbeln ALPHA = IN }|.
"--------------------------------------------------
" Read Header (VBAK)
"--------------------------------------------------
SELECT SINGLE
vbeln,
erdat,
ernam,
auart,
kunnr
FROM zdt_vbak
INTO _vbak
WHERE vbeln = _vbeln.
IF sy-subrc <> 0.
RETURN.
ENDIF.
"--------------------------------------------------
" Read Items (VBAP)
"--------------------------------------------------
SELECT
vbeln,
posnr,
matnr,
kwmeng,
vrkme
FROM zdt_vbap
INTO TABLE _vbap
WHERE vbeln = _vbeln.
"--------------------------------------------------
" Explicit Header Mapping (IMPORTANT)
"--------------------------------------------------
CLEAR ls_deep_str.
ls_deep_str-vbeln = ls_vbak-vbeln.
ls_deep_str-erdat = ls_vbak-erdat.
ls_deep_str-ernam = ls_vbak-ernam.
ls_deep_str-auart = ls_vbak-auart.
ls_deep_str-kunnr = ls_vbak-kunnr.
"--------------------------------------------------
" Items Mapping
"--------------------------------------------------
IF lt_vbap IS NOT INITIAL.
ls_deep_str-znavigation = CORRESPONDING #( lt_vbap ).
ENDIF.
"--------------------------------------------------
" Return Deep Entity
"--------------------------------------------------
copy_data_to_ref(
EXPORTING
is_data = ls_deep_str
CHANGING
cr_data = er_entity
).
APPEND 'znavigation' TO et_expanded_clauses.
ENDMETHOD. </code></pre><P> </P><P><STRONG>Method: <SPAN class=""><SPAN class="">/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET.</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P> </P><pre class="lia-code-sample language-abap"><code> method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET.
DATA : lt_vbak TYPE ZCL_ZK_DEEP_ENTITY_MPC_EXT=>tt_vbak,
lt_vbap TYPE ZCL_ZK_DEEP_ENTITY_MPC_EXT=>tt_vbap,
ls_deep type ZCL_ZK_DEEP_ENTITY_MPC_EXT=>ty_deep_str,
lt_deep TYPE STANDARD TABLE OF ZCL_ZK_DEEP_ENTITY_MPC_EXT=>ty_deep_str.
SELECT FROM zdt_vbak FIELDS VBELN,
ERDAT,
ERNAM,
AUART,
KUNNR INTO TABLE _vbak.
LOOP AT lt_vbak ASSIGNING FIELD-SYMBOL(<fs_vbak>).
clear ls_deep .
ls_deep = CORRESPONDING #( <fs_vbak> ).
SELECT FROM zdt_vbap FIELDS VBELN,
POSNR,
MATNR,
KWMENG,
VRKME
WHERE vbeln = @<fs_vbak>-vbeln
INTO TABLE _vbap.
ls_deep-znavigation = CORRESPONDING #( lt_vbak ).
APPEND ls_deep to lt_deep.
ENDLOOP.
copy_data_to_ref(
EXPORTING
is_data = lt_deep
CHANGING
cr_data = er_entityset
).
APPEND 'znavigation' to et_expanded_clauses.
endmethod. </code></pre><P> </P><P> <STRONG>Method: <SPAN class=""><SPAN class="">/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY.</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P> </P><pre class="lia-code-sample language-abap"><code> METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.
DATA : ls_deep TYPE zcl_zk_deep_entity_mpc_ext=>ty_deep_str,
ls_vbak TYPE zcl_zk_deep_entity_mpc_ext=>ts_vbak,
ls_vbap TYPE zcl_zk_deep_entity_mpc_ext=>ts_vbap,
ls_vbak2 TYPE zdt_vbak,
ls_vbap2 TYPE zdt_vbap,
lv_vbeln TYPE zdt_vbak-vbeln,
lv_posnr TYPE zdt_vbap-posnr,
lv_vbeln_n TYPE zdt_vbak-vbeln,
lv_posnr_n TYPE zdt_vbap-posnr.
io_data_provider->read_entry_data(
IMPORTING
es_data = ls_deep
).
SELECT MAX( vbeln )
INTO _vbeln
FROM zdt_vbak.
IF lv_vbeln IS INITIAL.
lv_vbeln_n = 1.
ELSE.
lv_vbeln_n = lv_vbeln + 1.
ENDIF.
lv_vbeln_n = |{ lv_vbeln_n ALPHA = IN }|.
ls_vbak-vbeln = lv_vbeln_n.
ls_vbak-erdat = sy-datum.
ls_vbak-ernam = sy-uname.
ls_vbak-auart = ls_deep-auart.
ls_vbak-kunnr = ls_deep-kunnr.
MOVE-CORRESPONDING ls_vbak TO ls_vbak2.
INSERT zdt_vbak FROM ls_vbak2.
CLEAR lv_posnr.
LOOP AT ls_deep-znavigation INTO DATA(ls_deep_item).
lv_posnr = lv_posnr + 10.
ls_vbap-vbeln = lv_vbeln_n.
ls_vbap-posnr = lv_posnr.
ls_vbap-matnr = ls_deep_item-matnr.
ls_vbap-kwmeng = ls_deep_item-kwmeng.
ls_vbap-vrkme = ls_deep_item-vrkme.
MOVE-CORRESPONDING ls_vbap TO ls_vbap2.
INSERT zdt_vbap FROM ls_vbap2.
CLEAR ls_vbap2.
ENDLOOP.
ls_deep-vbeln = lv_vbeln_n.
ls_deep-erdat = sy-datum.
copy_data_to_ref(
EXPORTING
is_data = ls_deep
CHANGING
cr_data = er_deep_entity
).
ENDMETHOD. </code></pre><P> </P><P><FONT size="6"><STRONG> <SPAN class="">UI5 </SPAN><SPAN class="">Implementation:</SPAN></STRONG></FONT></P><P><STRONG><FONT size="5"><SPAN class=""><SPAN class=""><SPAN class="">Step 1:</SPAN><SPAN class=""> View – Binding Data and Preparing Navigation:</SPAN></SPAN></SPAN></FONT></STRONG></P><UL><LI><SPAN>The view shows a list of sales orders by binding the table to the </SPAN><STRONG><SPAN>header entity (vbakSet)</SPAN></STRONG><SPAN>. When the screen loads, it automatically fetches only basic data (like order number, date, customer). It does not load item data here, so the screen stays fast and simple.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Each row in the table is made </SPAN><STRONG><SPAN>clickable</SPAN></STRONG><SPAN> and shows a small arrow because of the navigation type. This tells the user that clicking a row will take them to another screen.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>When a row is clicked, the view triggers an event and </SPAN><STRONG><SPAN>sends the selected row’s data to the controller</SPAN></STRONG><SPAN>. This includes the important key field (Vbeln), which is needed to identify the sales order.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>From a deep entity point of view, the view does not load full data. It only shows header data and </SPAN><STRONG><SPAN>prepares the key</SPAN></STRONG><SPAN>, so that the next screen can use it to fetch complete data (header + items) together.</SPAN><SPAN> </SPAN></LI></UL><P> </P><pre class="lia-code-sample language-markup"><code><mvc:View
controllerName="project1.controller.View1"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:f="sap.f"
displayBlock="true">
<f:DynamicPage
id="dynPage"
toggleHeaderOnTitleClick="false">
<!-- ================= TITLE ================= -->
<f:title>
<f:DynamicPageTitle>
<f:heading>
<HBox alignItems="Center">
<Avatar
src="sap-icon://sales-order"
displayShape="Square"
class="sapUiTinyMarginEnd"/>
<VBox>
<Title text="Sales Orders" level="H2"/>
<Text text="Manage and track sales orders"/>
</VBox>
</HBox>
</f:heading>
<f:actions>
<Button
text="Create"
icon="sap-icon://add"
type="Emphasized"
press="onCreate"/>
<!--
<Button
text="Edit"
icon="sap-icon://edit"
press="onUpdate"
enabled="{= ${vbakTable>/selectedItems}.length === 1 }"/>
-->
<Button
text="Delete"
icon="sap-icon://delete"
type="Negative"
press="onDelete"
enabled="{= ${vbakTable>/selectedItems}.length > 0 }"/>
</f:actions>
</f:DynamicPageTitle>
</f:title>
<!-- ================= HEADER ================= -->
<f:header>
<f:DynamicPageHeader pinnable="true">
<Toolbar design="Transparent">
<Label text="Search"/>
<SearchField
width="20rem"
liveChange="onSearch"
placeholder="Sales Order / Customer"/>
</Toolbar>
</f:DynamicPageHeader>
</f:header>
<!-- ================= CONTENT ================= -->
<f:content>
<Table
id="vbakTable"
items="{ path: '/vbakSet' }"
growing="true"
growingScrollToLoad="true"
mode="MultiSelect"
itemPress="onItemPress"
sticky="ColumnHeaders"
noDataText="No sales orders found"
busyIndicatorDelay="0">
<!-- ================= COLUMNS ================= -->
<columns>
<Column width="11rem">
<Text text="Sales Order"/>
</Column>
<Column width="9rem" demandPopin="true" minScreenWidth="Tablet">
<Text text="Created On"/>
</Column>
<Column width="9rem" demandPopin="true" minScreenWidth="Tablet">
<Text text="Created By"/>
</Column>
<Column width="7rem">
<Text text="Type"/>
</Column>
<Column width="11rem" demandPopin="true" minScreenWidth="Desktop">
<Text text="Customer"/>
</Column>
</columns>
<!-- ================= ITEMS ================= -->
<items>
<ColumnListItem
type="Navigation">
<cells>
<ObjectIdentifier
title="{Vbeln}"
titleActive="true"/>
<Text text="{Erdat}"/>
<Text text="{Ernam}"/>
<ObjectStatus
text="{Auart}"
state="Information"/>
<Text text="{Kunnr}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</f:content>
</f:DynamicPage>
</mvc:View></code></pre><P> </P><P><STRONG><SPAN class=""><SPAN class=""><SPAN class=""><SPAN class=""><SPAN class="">Step 2: </SPAN><SPAN class="">Controller – Handling Row Selection and Parameter-Based Routing:</SPAN></SPAN></SPAN></SPAN></SPAN></STRONG></P><UL><LI><SPAN>When the user clicks on a row, the controller takes that row and gets its data. From that data, it picks the </SPAN><STRONG><SPAN>Sales Order number (Vbeln)</SPAN></STRONG><SPAN>, which is the main key.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>After getting this key, the controller performs </SPAN><STRONG><SPAN>router-based navigation using parameter-based (dynamic) routing</SPAN></STRONG><SPAN>. It sends the user to the Detail page and passes the Vbeln as a parameter, so the next screen knows exactly which sales order to load.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>In terms of deep entity, the controller is not loading all the data here. It is just </SPAN><STRONG><SPAN>sending the key</SPAN></STRONG><SPAN>, and using that key, the next screen will fetch full data (header + items) together.</SPAN><SPAN> </SPAN></LI></UL><P> </P><pre class="lia-code-sample language-javascript"><code>sap.ui.define(
[
"sap/ui/core/mvc/Controller"
],
function (Controller) {
"use strict";
return Controller.extend("project1.controller.View1", {
onInit: function () {
},
onCreate: function () {
this.getOwnerComponent().getRouter().navTo("Create");
},
onItemPress: function (oEvent) {
debugger;
var sVbeln = oEvent
.getParameter("listItem")
.getBindingContext()
.getProperty("Vbeln");
this.getOwnerComponent().getRouter().navTo("Detail", {
Vbeln: sVbeln
});
}
});
}
);</code></pre><P> </P><P><STRONG><SPAN class=""><SPAN class=""><SPAN class=""><SPAN class=""> Output:</SPAN></SPAN></SPAN></SPAN></STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_8-1775559942535.png" style="width: 686px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394313i12138F17DEC88878/image-dimensions/686x318?v=v2" width="686" height="318" role="button" title="Unknown21_8-1775559942535.png" alt="Unknown21_8-1775559942535.png" /></span></P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Step 3: View – Showing Header and Item Data:</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></FONT></P><UL><LI><SPAN>The view is designed to show </SPAN><STRONG><SPAN>one sales order in detail</SPAN></STRONG><SPAN>. It displays both the </SPAN><STRONG><SPAN>header data</SPAN></STRONG><SPAN> (like order number, customer, date) and the </SPAN><STRONG><SPAN>item data</SPAN></STRONG><SPAN> (list of materials).</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>It uses a </SPAN><STRONG><SPAN>local model (</SPAN></STRONG><STRONG><SPAN>detail</SPAN></STRONG><STRONG><SPAN>)</SPAN></STRONG><SPAN> where data is divided into two parts:</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Header → main sales order</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Items → list of related items</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>The header section is bound to </SPAN><SPAN>detail>/Header</SPAN><SPAN>, and the table is bound to </SPAN><SPAN>detail>/Items</SPAN><SPAN>, so it can show </SPAN><STRONG><SPAN>parent + child data together</SPAN></STRONG><SPAN>.</SPAN><SPAN> </SPAN></LI></UL><P> </P><pre class="lia-code-sample language-markup"><code><mvc:View
controllerName="project1.controller.Detail"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:uxap="sap.uxap"
displayBlock="true">
<uxap:ObjectPageLayout
id="ObjectPage"
enableLazyLoading="true"
showHeaderContent="true"
showAnchorBar="true"
upperCaseAnchorBar="false"
isChildPage="true">
<!-- ================= HEADER ================= -->
<uxap:headerTitle>
<uxap:ObjectPageHeader
objectTitle="{detail>/Header/Vbeln}"
objectSubtitle="Sales Order"
objectImageURI="sap-icon://sales-order"
objectImageShape="Square"
isObjectIconAlwaysVisible="true">
<!-- Header Actions (Fiori standard) -->
<uxap:actions>
<Button
icon="sap-icon://nav-back"
type="Emphasized"
tooltip="Back"
press="onNavBack"/>
<Button
icon="sap-icon://edit"
text="Edit"
type="Attention"/>
</uxap:actions>
</uxap:ObjectPageHeader>
</uxap:headerTitle>
<!-- ================= HEADER CONTENT ================= -->
<uxap:headerContent>
<HBox
justifyContent="Start"
alignItems="Center"
class="sapUiSmallMargin">
<ObjectStatus
title="Document Type"
text="{detail>/Header/Auart}"
state="Information"/>
</HBox>
</uxap:headerContent>
<!-- ================= SECTIONS ================= -->
<uxap:sections>
<!-- ================= GENERAL INFORMATION ================= -->
<uxap:ObjectPageSection
title="General Information"
titleUppercase="false">
<uxap:subSections>
<uxap:ObjectPageSubSection>
<VBox class="sapUiMediumMargin sapUiResponsiveContentPadding">
<HBox wrap="Wrap" class="sapUiSmallMarginBottom">
<VBox width="18rem" class="sapUiSmallMarginEnd">
<Label text="Customer"/>
<ObjectIdentifier title="{detail>/Header/Kunnr}"/>
</VBox>
<VBox width="18rem" class="sapUiSmallMarginEnd">
<Label text="Created On"/>
<Text text="{detail>/Header/Erdat}"/>
</VBox>
<VBox width="18rem">
<Label text="Created By"/>
<Text text="{detail>/Header/Ernam}"/>
</VBox>
</HBox>
</VBox>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
<!-- ================= ITEMS ================= -->
<uxap:ObjectPageSection
title="Items"
titleUppercase="true">
<uxap:subSections>
<uxap:ObjectPageSubSection>
<Table
items="{detail>/Items}"
growing="true"
growingScrollToLoad="true"
sticky="HeaderToolbar,ColumnHeaders"
class="sapUiResponsiveContentPadding">
<!-- Section Toolbar (Fiori pattern) -->
<headerToolbar>
<OverflowToolbar>
<Title text="Order Items" level="H3"/>
<ToolbarSpacer/>
<Text text="Items: {= ${detail>/Items}.length }"/>
<ToolbarSeparator/>
<Button
icon="sap-icon://add"
text="Add Item"
type="Transparent"/>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column width="5rem">
<Text text="Item"/>
</Column>
<Column>
<Text text="Material"/>
</Column>
<Column hAlign="End" width="8rem">
<Text text="Quantity"/>
</Column>
<Column width="6rem">
<Text text="Unit"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<ObjectIdentifier title="{detail>Posnr}"/>
<Text text="{detail>Matnr}"/>
<ObjectNumber number="{detail>Kwmeng}"/>
<ObjectStatus text="{detail>Vrkme}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
</uxap:sections>
<!-- ================= FOOTER (Fiori standard) ================= -->
<uxap:footer>
<OverflowToolbar>
<ToolbarSpacer/>
<Button
text="Edit"
icon="sap-icon://edit"
type="Emphasized"/>
<Button
text="Cancel"
type="Transparent"
press="onNavBack"/>
</OverflowToolbar>
</uxap:footer>
</uxap:ObjectPageLayout>
</mvc:View></code></pre><P> </P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Step 4:</SPAN></SPAN><SPAN class=""><SPAN class=""> </SPAN></SPAN><SPAN class=""><SPAN class="">Controller – Fetching Deep Entity Data:</SPAN></SPAN></STRONG></FONT></P><UL><LI><SPAN>The controller gets the </SPAN><STRONG><SPAN>Vbeln (Sales Order number)</SPAN></STRONG><SPAN> from routing when the screen opens.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Using this key, it makes </SPAN><STRONG><SPAN>one OData call with </SPAN></STRONG><STRONG><SPAN>$expand</SPAN></STRONG><SPAN>, which fetches:</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Header data</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Item data</SPAN><SPAN> </SPAN></LI></UL><P><SPAN>in a single request (deep entity).</SPAN><SPAN> </SPAN></P><UL><LI><SPAN>After getting the data, it splits it into:</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Header → stored separately</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Items → stored separately</SPAN><SPAN> </SPAN></LI></UL><P><SPAN>and sets it into the local model, which is then shown in the view.</SPAN><SPAN> </SPAN></P><P> </P><pre class="lia-code-sample language-javascript"><code>sap.ui.define(
[
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
],
function (Controller, JSONModel) {
"use strict";
return Controller.extend("project1.controller.Detail", {
onInit: function () {
debugger;
this.getOwnerComponent()
.getRouter()
.getRoute("Detail")
.attachPatternMatched(this._onObjectMatched, this);
this.getView().setModel(
new JSONModel({
Header: {},
Items: []
}),
"detail"
);
},
_onObjectMatched: function (oEvent) {
debugger;
var sVbeln = oEvent.getParameter("arguments").Vbeln;
sVbeln = sVbeln.padStart(10, "0");
var oModel = this.getOwnerComponent().getModel();
var oDetailModel = this.getView().getModel("detail");
oModel.read("/vbakSet('" + sVbeln + "')", {
urlParameters: {
"$expand": "znavigation"
},
success: function (oData) {
debugger;
oDetailModel.setProperty("/Header", oData);
oDetailModel.setProperty(
"/Items",
oData.znavigation.results
);
},
error: function () {
debugger;
}
});
},
onNavBack: function () {
this.getOwnerComponent()
.getRouter()
.navTo("RouteView1");
}
});
}
);</code></pre><P> </P><P><FONT size="5"><STRONG><SPAN class=""> Output:</SPAN></STRONG></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_9-1775560181277.png" style="width: 675px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394314i8F6BB64C03003030/image-dimensions/675x313?v=v2" width="675" height="313" role="button" title="Unknown21_9-1775560181277.png" alt="Unknown21_9-1775560181277.png" /></span></P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class="">Step 5:</SPAN></SPAN><SPAN class=""><SPAN class=""> </SPAN></SPAN><SPAN class=""><SPAN class="">View – Entering Header and Item Data:</SPAN></SPAN></STRONG></FONT></P><UL><LI><SPAN>The view is designed to </SPAN><STRONG><SPAN>create a new sales order</SPAN></STRONG><SPAN>. It allows the user to enter both </SPAN><STRONG><SPAN>header data (like document type, customer)</SPAN></STRONG><SPAN> and </SPAN><STRONG><SPAN>item data (materials, quantity, unit)</SPAN></STRONG><SPAN> in the same screen.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>It uses a </SPAN><STRONG><SPAN>local model (</SPAN></STRONG><STRONG><SPAN>local</SPAN></STRONG><STRONG><SPAN>)</SPAN></STRONG><SPAN> to store user input. The header fields are directly bound to this model, and the items table is bound to </SPAN><SPAN>local>/Items</SPAN><SPAN>, which holds multiple item entries.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>The user can dynamically </SPAN><STRONG><SPAN>add or remove items</SPAN></STRONG><SPAN>, so the view supports multiple child entries under one header.</SPAN><SPAN> </SPAN></LI></UL><P> </P><pre class="lia-code-sample language-markup"><code><mvc:View
controllerName="project1.controller.Create"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:uxap="sap.uxap"
xmlns:form="sap.ui.layout.form">
<uxap:ObjectPageLayout
id="CreateSalesOrderPage"
showHeaderContent="true">
<!-- ================= HEADER ================= -->
<uxap:headerTitle>
<uxap:ObjectPageHeader
objectTitle="Create Sales Order"
objectSubtitle="Header and Items"
objectImageURI="sap-icon://sales-order"
objectImageShape="Square">
<uxap:actions>
<Button
text="Save"
icon="sap-icon://save"
type="Emphasized"
press="onSave"/>
<Button
text="Cancel"
icon="sap-icon://cancel"
type="Reject"
press="onCancel"/>
</uxap:actions>
</uxap:ObjectPageHeader>
</uxap:headerTitle>
<!-- ================= SECTIONS ================= -->
<uxap:sections>
<!-- ================= HEADER DATA ================= -->
<uxap:ObjectPageSection title="Header Data">
<uxap:subSections>
<uxap:ObjectPageSubSection>
<form:SimpleForm
editable="true"
layout="ResponsiveGridLayout"
labelSpanXL="3"
labelSpanL="3"
labelSpanM="4"
labelSpanS="12">
<Label text="Sales Document Type"/>
<Input
value="{local>/Auart}"
id="Aurat"
placeholder="AUART"
showValueHelp="true"
valueHelpRequest="onAuartValueHelp"/>
<Label text="Customer"/>
<Input
id="Kunnr"
value="{local>/Kunnr}"
placeholder="KUNNR"/>
<Label text="Created On"/>
<DatePicker editable="false"/>
<Label text="Created By"/>
<Input editable="false"/>
</form:SimpleForm>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
<!-- ================= ITEM DATA ================= -->
<uxap:ObjectPageSection title="Items">
<uxap:subSections>
<uxap:ObjectPageSubSection>
<Table
id="itemTable"
mode="MultiSelect"
growing="true"
items="{
path: 'local>/Items'
}">
<headerToolbar>
<Toolbar>
<Title text="Sales Order Items"/>
<ToolbarSpacer/>
<Button
icon="sap-icon://add"
text="Add Item"
press="onAddItem"/>
<Button
icon="sap-icon://delete"
text="Remove Item"
press="onRemoveItem"/>
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Text text="Item"/>
</Column>
<Column>
<Text text="Material"/>
</Column>
<Column hAlign="End">
<Text text="Quantity"/>
</Column>
<Column>
<Text text="Unit"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Input
value="{local>Posnr}"
editable="false"/>
<Input
value="{local>Matnr}"
placeholder="MATNR"/>
<Input
type="Number"
value="{local>Kwmeng}"
placeholder="Quantity"/>
<Input
value="{local>Vrkme}"
placeholder="Unit"/>
</cells>
</ColumnListItem>
</items>
</Table>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
</uxap:sections>
</uxap:ObjectPageLayout>
</mvc:View></code></pre><P> </P><P><FONT size="5"><STRONG><SPAN class=""><SPAN class=""><SPAN class="">Step 6:</SPAN></SPAN></SPAN><SPAN class=""><SPAN class=""><SPAN class="">Creating Deep Entity (Header + Items):</SPAN></SPAN></SPAN></STRONG></FONT></P><UL><LI><SPAN>The controller manages user input and stores all item data in the </SPAN><STRONG><SPAN>local model</SPAN></STRONG><SPAN>. When the user clicks save, it collects both header and item data. </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>It creates a </SPAN><STRONG><SPAN>single payload</SPAN></STRONG><SPAN> that contains: </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Header data (Auart, Kunnr, etc.) </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Item data (array of items) </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>Then it makes one </SPAN><STRONG><SPAN>create a call to backend</SPAN></STRONG><SPAN>, sending everything together. </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>After successful creation, it reads the latest sales order and </SPAN><STRONG><SPAN>navigates to the Detail page</SPAN></STRONG><SPAN> using the generated Vbeln.</SPAN><SPAN> </SPAN></LI></UL><P> </P><pre class="lia-code-sample language-javascript"><code>sap.ui.define(
[
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/m/MessageToast"
],
function (Controller, JSONModel, MessageToast) {
"use strict";
return Controller.extend("project1.controller.Create", {
onInit: function () {
// Local JSON model for dynamic items
var oData = {
Items: []
};
var oLocalModel = new JSONModel(oData);
this.getView().setModel(oLocalModel, "local");
},
/* =========================================================== */
/* NAVIGATION */
/* =========================================================== */
onCancel: function () {
this.getOwnerComponent()
.getRouter()
.navTo("RouteView1");
},
/* =========================================================== */
/* VALUE HELP */
/* =========================================================== */
oAuartVh: null,
onAuartValueHelp: function () {
if (!this.oAuartVh) {
this.oAuartVh = sap.ui.xmlfragment(
"project1.Fragments.AuartVH",
this
);
this.getView().addDependent(this.oAuartVh);
}
this.oAuartVh.open();
},
onAuartCancel: function () {
this.oAuartVh.close();
},
onAuartConfirm: function (oEvent) {
var oItem = oEvent.getParameter("selectedItem");
if (!oItem) {
return;
}
this.byId("Aurat").setValue(oItem.getTitle());
},
onExit: function () {
if (this.oAuartVh) {
this.oAuartVh.destroy();
this.oAuartVh = null;
}
},
/* =========================================================== */
/* ADD ITEM */
/* =========================================================== */
onAddItem: function () {
var oModel = this.getView().getModel("local");
var aItems = oModel.getProperty("/Items");
aItems.push({
Posnr: "",
Matnr: "",
Kwmeng: "",
Vrkme: ""
});
oModel.setProperty("/Items", aItems);
},
/* =========================================================== */
/* REMOVE ITEM */
/* =========================================================== */
onRemoveItem: function () {
var oTable = this.byId("itemTable");
var oModel = this.getView().getModel("local");
var aItems = oModel.getProperty("/Items");
var aSelectedItems = oTable.getSelectedItems();
if (aSelectedItems.length === 0) {
MessageToast.show("Select at least one item to delete");
return;
}
aSelectedItems.forEach(function (oItem) {
var sPath = oItem
.getBindingContext("local")
.getPath();
var iIndex = parseInt(sPath.split("/")[2]);
aItems.splice(iIndex, 1);
});
oModel.setProperty("/Items", aItems);
},
/* =========================================================== */
/* SAVE (DEEP ENTITY CREATE) */
/* =========================================================== */
onSave: function () {
debugger;
var oModel = this.getOwnerComponent().getModel();
var aItems = this.getView()
.getModel("local")
.getProperty("/Items");
if (aItems.length === 0) {
MessageToast.show("Please add at least one item");
return;
}
var oPayload = {
Auart: this.byId("Aurat").getValue(),
Kunnr: this.byId("Kunnr").getValue(),
Erdat: new Date().toISOString().split("T")[0],
znavigation: aItems
};
oModel.create("/vbakSet", oPayload, {
success: (oData) => {
this._readLatestOrder();
MessageToast.show("Sales Order Created");
// Clear header fields
this.byId("Aurat").setValue("");
this.byId("Kunnr").setValue("");
// Clear items
this.getView()
.getModel("local")
.setProperty("/Items", []);
},
error: (oError) => {
MessageToast.show("Error while creating Sales Order");
}
});
},
/* =========================================================== */
/* READ LATEST ORDER */
/* =========================================================== */
_readLatestOrder: function () {
var oModel = this.getOwnerComponent().getModel();
oModel.read("/vbakSet", {
urlParameters: {
"$orderby": "Vbeln desc"
},
success: function (oData) {
if (oData.results.length > 0) {
var sVbeln = oData.results[0].Vbeln;
this.getOwnerComponent()
.getRouter()
.navTo("Detail", {
Vbeln: sVbeln
});
}
}.bind(this),
error: function () {
MessageToast.show("Read failed");
}
});
}
});
}
);</code></pre><P> </P><UL><LI><SPAN>Here view collects full data (header + items) </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>The controller sends full data in one call (</SPAN><STRONG><SPAN>deep insert</SPAN></STRONG><SPAN>) </SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>This completes the deep entity flow for </SPAN><STRONG><SPAN>create scenario</SPAN></STRONG><SPAN> </SPAN></LI></UL><P><FONT size="5"><STRONG><SPAN class=""><SPAN class=""><SPAN class=""><SPAN class="">Output:</SPAN></SPAN></SPAN></SPAN></STRONG></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_10-1775560355658.png" style="width: 674px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394315i10E2C94A83501F63/image-dimensions/674x311?v=v2" width="674" height="311" role="button" title="Unknown21_10-1775560355658.png" alt="Unknown21_10-1775560355658.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Unknown21_11-1775560376331.png" style="width: 680px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394316iD5CA786A8206D9AC/image-dimensions/680x316?v=v2" width="680" height="316" role="button" title="Unknown21_11-1775560376331.png" alt="Unknown21_11-1775560376331.png" /></span></P><UL><LI><STRONG> Conclusion</STRONG></LI></UL><P>Deep Entity simplifies handling <STRONG>header and item data in a single request</STRONG>, reducing multiple OData calls and keeping both backend and UI logic clean.</P><P>In this blog, we covered the complete lifecycle:</P><UL><LI>Backend setup using SEGW</LI><LI>Data retrieval using $expand</LI><LI>Deep insert (header + items in one call)</LI><LI>UI5 integration.</LI></UL>2026-04-13T07:15:04.408000+02:00https://community.sap.com/t5/human-capital-management-blog-posts-by-sap/csv-validator-app-is-now-open-source/ba-p/14376711CSV Validator App Is Now Open Source2026-04-17T10:06:11.296000+02:00DivyaTiwarihttps://community.sap.com/t5/user/viewprofilepage/user-id/17995<H2 id="toc-hId-1794263752">From Solution to Community Tool</H2><P>A few weeks ago, I shared how <A href="https://community.sap.com/t5/human-capital-management-blog-posts-by-sap/bridging-data-quality-gaps-in-sap-successfactors-tih-with-csvvalidationapp/ba-p/14283170" target="_blank">CSVValidationApp helps solve data quality issues in SAP SuccessFactors Talent Intelligence Hub</A>. The response surprised me. Many have built similar workarounds, spent hours cleaning data manually, or watched perfectly good imports fail because of stray HTML tags.</P><P>That's when I felt this shouldn't be "my tool." It should be <EM>our</EM> tool.</P><P><STRONG>Today, CSV Validator App is officially open source</STRONG> and available on GitHub under the Apache 2.0 license: <A href="https://github.com/SAP/csv-validator" target="_blank" rel="noopener noreferrer nofollow">github.com/SAP/csv-validator</A></P><H2 id="toc-hId-1597750247">Why This Matters</H2><P>I didn't build this tool because I love CSV files (I don't). I built it because I was tired of seeing good work derailed by preventable issues. An HR team prepares a skills library update, exports clean data, imports it into TIH—and suddenly descriptions are broken, special characters are corrupted, and they're troubleshooting instead of enabling their workforce.</P><P>It's frustrating. And it's common.</P><P>Making this open source isn't about recognition or downloads. It's about honesty: <STRONG>I don't have all the answers.</STRONG> You might be importing recruiting data with different quirks. You might support a region with specific character encoding needs. You might have found a validation rule I missed.</P><P>By opening the code, we can solve these problems together—transparently, collaboratively, and faster than any of us could alone.</P><H2 id="toc-hId-1401236742">What You're Getting</H2><P>This is a complete SAP Fiori application you can run today:</P><P><STRONG>Core Validation:</STRONG></P><UL><LI>Detects encoding issues (UTF-8 compliance, BOM, null bytes)</LI><LI>Validates CSV structure (headers, delimiters, column consistency)</LI><LI>Identifies problematic content (HTML tags, entities, control characters, special characters)</LI><LI>Checks field lengths and data integrity</LI></UL><P><STRONG>Auto-Correction:</STRONG></P><UL><LI>Strips HTML tags while preserving content</LI><LI>Converts HTML entities to UTF-8 characters (<CODE>&nbsp;</CODE><SPAN> </SPAN>→ space,<SPAN> </SPAN><CODE>&uuml;</CODE><SPAN> </SPAN>→ ü)</LI><LI>Properly escapes special characters</LI><LI>Generates a clean, download-ready corrected file</LI></UL><P><STRONG>UI Features:</STRONG></P><UL><LI>Drag-and-drop file upload</LI><LI>Interactive preview of your CSV</LI><LI>Filterable table showing issues by row and type</LI><LI>Side-by-side view of original vs. corrected content</LI><LI>One-click download of the corrected file</LI></UL><P><STRONG>Privacy:</STRONG></P><UL><LI>Everything runs locally in your browser</LI><LI>No uploads, no servers, no data leaves your machine</LI></UL><P>It's built with SAP UI5, follows SAP Fiori standards, and runs via npm. Five minutes from clone to validation.</P><H2 id="toc-hId-1204723237">Getting Started</H2><DIV class=""><PRE><CODE>git clone https://github.com/SAP/csv-validator.git
cd csv-validator
npm install
npm start</CODE></PRE></DIV><P>Open your browser to the app url, drop in a CSV file, and click Validate. That's it.<BR />You can test by uploading your csv and press validate. Here is a sample screenshot of what you can expect:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="DivyaTiwari_0-1776410454647.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/399385i1DD02EEAF6A7DF00/image-size/large?v=v2&px=999" role="button" title="DivyaTiwari_0-1776410454647.png" alt="DivyaTiwari_0-1776410454647.png" /></span></P><P> </P><H2 id="toc-hId-1008209732">Where We Go From Here</H2><P>I have ideas for improvements—support for other SuccessFactors modules, batch processing, direct API integration. But I'm more interested in hearing yours.</P><P><STRONG>If you use this tool and it helps, tell me what's missing.</STRONG> If it doesn't catch an issue it should, open a GitHub issue with an example. If you have a fix or enhancement, submit a pull request. If you just want to share your experience, leave a comment below.</P><P>This isn't a finished product. It's a starting point. I'm learning as much from your use cases as you might learn from the code.</P><H2 id="toc-hId-811696227">An Honest Ask</H2><P>If you work with SuccessFactors data imports—whether you're an administrator, consultant, or developer—try this tool with your real files. Not a sanitized demo file. Your actual data (with sensitive info removed, of course).</P><P>Then tell me:</P><UL><LI>Did it catch issues you would have missed?</LI><LI>Did it flag false positives that aren't actually problems?</LI><LI>What validation rule would make your life easier?</LI></UL><P>And if you've built something similar or have ideas for collaboration, let's talk. The goal isn't to centralize everything into this one tool—it's to raise the baseline for data quality across the community.</P><HR /><P><STRONG>Resources:</STRONG></P><UL><LI><STRONG>GitHub Repository:</STRONG><SPAN> </SPAN><A href="https://github.com/SAP/csv-validator" target="_blank" rel="noopener noreferrer nofollow">github.com/SAP/csv-validator</A></LI><LI><STRONG>Original Blog Post:</STRONG><SPAN> </SPAN><A href="https://community.sap.com/t5/human-capital-management-blog-posts-by-sap/bridging-data-quality-gaps-in-sap-successfactors-tih-with-csvvalidationapp/ba-p/14283170" target="_blank">Bridging Data Quality Gaps in TIH with CSVValidationApp</A></LI><LI><STRONG>Issues & Feedback:</STRONG><SPAN> </SPAN><A href="https://github.com/SAP/csv-validator/issues" target="_blank" rel="noopener noreferrer nofollow">github.com/SAP/csv-validator/issues</A></LI><LI><STRONG>Contribution Guidelines:</STRONG><SPAN> </SPAN><A href="https://github.com/SAP/csv-validator/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer nofollow">github.com/SAP/csv-validator/CONTRIBUTING.md</A></LI></UL><P>Data quality shouldn't be a bottleneck. Let's make it a strength—together.</P>2026-04-17T10:06:11.296000+02:00https://community.sap.com/t5/frontend-ui5-sap-fiori-blog-posts/how-to-integrate-ui5-test-coverage-with-sonarqube-in-sap-ui5-projects/ba-p/14379500How to Integrate UI5 Test Coverage with SonarQube in SAP UI5 Projects2026-04-21T15:19:13.771000+02:00Andrei_Yurahahttps://community.sap.com/t5/user/viewprofilepage/user-id/1738994<P>When working with SAP UI5 applications, automated tests are already a good practice. But once the project grows, test execution alone is no longer enough. Teams want to see <STRONG>how much of the application is actually covered by tests</STRONG>, especially in pull requests and CI/CD pipelines.</P><P>In this post, I will show how I implemented <STRONG>test coverage reporting for a SAP UI5 application</STRONG> and integrated it with <STRONG>SonarQube</STRONG> so that coverage metrics are visible directly in the quality dashboard.</P><P>The solution is based on:</P><UL><LI><CODE>ui5-test-runner</CODE> for running QUnit tests with coverage enabled</LI><LI><CODE>nyc</CODE> for generating LCOV reports</LI><LI>a custom normalization step to include untested files</LI><LI>SonarQube for importing and displaying coverage metrics</LI></UL><P>This setup works especially well in CI pipelines and helps teams track both <STRONG>coverage on new code</STRONG> and <STRONG>overall project coverage</STRONG>.</P><HR /><H2 id="toc-hId-1794351171">Why This Is Needed</H2><P>In many UI5 projects, unit tests exist, but coverage is not published anywhere centrally. As a result:</P><UL><LI>developers do not see how well new changes are covered</LI><LI>pull requests cannot be validated against coverage quality gates</LI><LI>SonarQube shows no meaningful UI coverage data</LI><LI>uncovered source files may be silently ignored</LI></UL><P>The main challenge is that in UI5 projects, coverage collection is not always straightforward when tests are executed in the browser. Even if coverage is enabled, the generated report may contain only files that were actually loaded during test execution. This creates an incomplete picture for SonarQube.</P><P>To solve this, I implemented an approach that not only generates LCOV coverage but also normalizes it so that <STRONG>all relevant source files are represented</STRONG>, including files with 0% coverage.</P><HR /><H2 id="toc-hId-1597837666">Solution Overview</H2><P>The final flow looks like this:</P><OL><LI><STRONG><CODE>ui5-test-runner</CODE></STRONG> runs QUnit tests with coverage instrumentation</LI><LI><STRONG><CODE>nyc</CODE></STRONG> generates the LCOV report</LI><LI><STRONG>a custom script normalizes the report</STRONG> and adds missing source files</LI><LI><STRONG>SonarQube imports the LCOV file</STRONG> and displays the coverage metrics</LI></OL><P>This gives a reliable and CI-friendly setup for SAP UI5 applications.</P><HR /><H2 id="toc-hId-1401324161">Prerequisites</H2><P>Install the required development dependencies:</P><PRE>npm install --save-dev ui5-test-runner nyc puppeteer</PRE><H3 id="toc-hId-1333893375">What each package is used for</H3><DIV class=""><DIV class="">Package Purpose <TABLE><TBODY><TR><TD><CODE>ui5-test-runner</CODE></TD><TD>Runs UI5/QUnit tests and supports code coverage</TD></TR><TR><TD><CODE>nyc</CODE></TD><TD>Istanbul-based coverage engine used under the hood</TD></TR><TR><TD><CODE>puppeteer</CODE></TD><TD>Runs tests in headless Chrome, useful for CI</TD></TR></TBODY></TABLE></DIV></DIV><HR /><H2 id="toc-hId-1008297151"><SPAN>Step 1. Configure <CODE>ui5-test-runner</CODE></SPAN></H2><P>Create a <CODE>ui5-test-runner.json</CODE> file with the basic setup:</P><pre class="lia-code-sample language-json"><code>{
"pageTimeout": 60000,
"coverage": true,
"coverageReportDir": "coverage",
"reportDir": "report",
"parallel": 2
}</code></pre><H3 id="toc-hId-940866365">What this configuration does</H3><UL><LI>enables coverage collection</LI><LI>stores coverage artifacts in the <CODE>coverage</CODE> folder</LI><LI>defines a timeout for browser-based execution</LI><LI>allows parallel test execution for better performance</LI></UL><HR /><H2 id="toc-hId-615270141">Step 2. Configure NYC</H2><P>Even though <CODE>ui5-test-runner</CODE> handles much of the work, it relies on NYC internally.<BR />That is why adding an explicit <CODE>.nycrc.json</CODE> file is important.</P><pre class="lia-code-sample language-json"><code>{
"all": true,
"sourceMap": false,
"reporter": ["lcov", "text-summary"],
"report-dir": "./coverage",
"temp-dir": "./.nyc_output",
"include": ["webapp/**/*.js"],
"exclude": ["webapp/test/**", "webapp/localService/**"],
"cwd": "."
}</code></pre><H3 id="toc-hId-547839355">Important points here</H3><UL><LI><CODE>all: true</CODE> is important because we want full project visibility</LI><LI>test sources are excluded from business code coverage</LI><LI><CODE>lcov</CODE> is required because this is the format SonarQube imports</LI></UL><HR /><H2 id="toc-hId-222243131">Step 3. Configure SonarQube</H2><P>Now we need to tell SonarQube where the UI5 sources, tests, and LCOV report are located.</P><P>Create or update <CODE>sonar-project.properties</CODE>:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""> </DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV><pre class="lia-code-sample language-bash"><code>sonar.projectKey=your-project-key
sonar.projectName=your-project-name
# Source configuration
sonar.sources=webapp/
sonar.exclusions=webapp/localService/**,**/node_modules/**
# Test configuration
sonar.tests=webapp/test/
sonar.test.inclusions=webapp/test/**/*.js
# Coverage report path
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.coverage.exclusions=webapp/test/**,webapp/localService/**
# Encoding
sonar.sourceEncoding=UTF-8</code></pre><P>At this point, the most important property is:</P><pre class="lia-code-sample language-bash"><code>sonar.javascript.lcov.reportPaths=coverage/lcov.info</code></pre><P>This is the file SonarQube reads to compute the coverage metrics.</P><HR /><H2 id="toc-hId-25729626">Step 4. Add NPM Scripts</H2><P>The next step is to automate local and CI execution.</P><P>In <CODE>package.json</CODE>:</P><pre class="lia-code-sample language-json"><code>{
"scripts": {
"test": "ui5 serve --config ui5-test.yaml --port 8080 & SERVER_PID=$!; sleep 3; ui5-test-runner --url http://localhost:8080/test/unit/unitTests.qunit.html --coverage --coverage-proxy; TEST_EXIT=$?; kill $SERVER_PID 2>/dev/null || true; exit $TEST_EXIT",
"test:ci": "ui5 serve --config ui5-test.yaml --port 8080 & SERVER_PID=$!; sleep 3; ui5-test-runner --url http://localhost:8080/test/unit/unitTests.qunit.html --coverage --coverage-proxy --ci; TEST_EXIT=$?; kill $SERVER_PID 2>/dev/null || true; npm run coverage:normalize; exit $TEST_EXIT",
"coverage:normalize": "node scripts/normalize-coverage.js"
}
}</code></pre><H3 id="toc-hId--116932529"><SPAN>Why <CODE>--coverage-proxy</CODE> is important</SPAN></H3><P>When UI5 tests are executed through a served application URL, <CODE>--coverage-proxy</CODE> enables on-the-fly instrumentation. Without it, coverage may be missing or incomplete.</P><H3 id="toc-hId--313446034">Key flags</H3><DIV class=""><DIV class="">Flag Meaning <TABLE><TBODY><TR><TD><CODE>--coverage</CODE></TD><TD>Enables coverage collection</TD></TR><TR><TD><CODE>--coverage-proxy</CODE></TD><TD>Instruments files dynamically in browser-based execution</TD></TR><TR><TD><CODE>--ci</CODE></TD><TD>Uses CI-friendly non-interactive output</TD></TR></TBODY></TABLE></DIV></DIV><HR /><H2 id="toc-hId--216556532">Step 5. Normalize Coverage for Untested Files</H2><P>This was the most important part of the implementation.</P><H3 id="toc-hId--706473044">The problem</H3><P>When <CODE>--coverage-proxy</CODE> is used, only files that are actually loaded during the test run are instrumented.<BR />That means if a source file is never loaded, it may not appear in <CODE>lcov.info</CODE> at all.</P><P>For SonarQube, this is problematic because missing files are not always treated the same way as explicitly uncovered files. As a result, the reported coverage can be misleading.</P><H3 id="toc-hId--902986549">The fix</H3><P>I added a normalization script that:</P><OL><LI>scans all source files in <CODE>webapp</CODE></LI><LI>checks which files are already present in <CODE>lcov.info</CODE></LI><LI>adds missing source files with 0% coverage</LI><LI>normalizes paths so that they match SonarQube expectations</LI></OL><P>Create <CODE>scripts/normalize-coverage.js</CODE>:</P><pre class="lia-code-sample language-javascript"><code>const fs = require('fs');
const path = require('path');
const lcovPath = 'coverage/lcov.info';
const webappDir = 'webapp';
// Get all JS source files (excluding test and localService)
function getAllSourceFiles() {
const files = [];
function walk(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
if (entry.name !== 'test' && entry.name !== 'localService' && entry.name !== 'node_modules') {
walk(fullPath);
}
} else if (entry.name.endsWith('.js')) {
const relativePath = path.relative(webappDir, fullPath).replace(/\\/g, '/');
files.push(relativePath);
}
}
}
walk(webappDir);
return files;
}
// Parse existing lcov.info to get covered files
function parseLcov(content) {
const covered = new Set();
for (const line of content.split('\n')) {
if (line.startsWith('SF:')) {
covered.add(line.slice(3));
}
}
return covered;
}
// Generate lcov entry for uncovered file
function generateUncoveredEntry(filePath) {
const fullPath = path.join(webappDir, filePath);
if (!fs.existsSync(fullPath)) return null;
const content = fs.readFileSync(fullPath, 'utf8');
const lines = content.split('\n');
const executableLines = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line &&
!line.startsWith('//') &&
!line.startsWith('/*') &&
!line.startsWith('*') &&
line !== '{' &&
line !== '}' &&
line !== '});' &&
line !== ']);' &&
line !== '};' &&
line !== '"use strict";') {
executableLines.push(i + 1);
}
}
if (executableLines.length === 0) return null;
let entry = `SF:${filePath}\n`;
entry += `FNF:0\nFNH:0\n`;
for (const lineNum of executableLines) {
entry += `DA:${lineNum},0\n`;
}
entry += `LF:${executableLines.length}\nLH:0\n`;
entry += `BRF:0\nBRH:0\n`;
entry += `end_of_record\n`;
return entry;
}
// Main
if (!fs.existsSync(lcovPath)) {
console.log('No lcov.info found, skipping');
process.exit(0);
}
let content = fs.readFileSync(lcovPath, 'utf8');
const lines = content.split('\n');
const normalized = [];
// Normalize paths (remove webapp/ prefix to match sonar.sources)
for (const line of lines) {
if (line.startsWith('SF:')) {
let filePath = line.slice(3);
const webappMatch = filePath.match(/[/\\]?webapp[/\\](.+)$/);
if (webappMatch) {
filePath = webappMatch[1];
}
filePath = filePath.replace(/\\/g, '/').replace(/^\//, '');
normalized.push('SF:' + filePath);
} else {
normalized.push(line);
}
}
// Get already covered files
const coveredFiles = parseLcov(normalized.join('\n'));
// Add uncovered files
const allFiles = getAllSourceFiles();
let uncoveredContent = '';
for (const file of allFiles) {
if (!coveredFiles.has(file)) {
const entry = generateUncoveredEntry(file);
if (entry) uncoveredContent += entry;
}
}
fs.writeFileSync(lcovPath, normalized.join('\n') + '\n' + uncoveredContent);
console.log('Coverage normalized for SonarQube');</code></pre><HR /><H2 id="toc-hId--806097047">A Critical Detail: Path Mapping Between LCOV and SonarQube</H2><P>This part is easy to overlook, but it is often the real reason why SonarQube shows 0% coverage even when the LCOV file exists.</P><P>If SonarQube is configured with:</P><pre class="lia-code-sample language-bash"><code>sonar.sources=webapp/</code></pre><P>then SonarQube treats <CODE>webapp/</CODE> as the root of the source tree.</P><P>That means:</P><UL><LI><CODE>webapp/model/messages.js</CODE> is indexed by SonarQube as <CODE>model/messages.js</CODE></LI><LI>therefore <CODE>lcov.info</CODE> must contain:</LI></UL><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class=""> </DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV><pre class="lia-code-sample language-javascript"><code>SF:model/messages.js</code></pre><DIV class=""><SPAN>and </SPAN><STRONG>not</STRONG><SPAN>:</SPAN></DIV><pre class="lia-code-sample language-json"><code>SF:webapp/model/messages.js</code></pre><H3 id="toc-hId--1296013559">In other words</H3><P>The path in <CODE>SF:</CODE> must be <STRONG>relative to <CODE>sonar.sources</CODE></STRONG>.</P><P>That is exactly why the normalization script rewrites the paths.</P><HR /><H2 id="toc-hId--1199124057">CI/CD Integration</H2><P>Once the local setup works, integrating it into the pipeline is straightforward.</P><H3 id="toc-hId--1689040569">SAP Piper example</H3><P>In <CODE>.pipeline/config.yml</CODE>:</P><pre class="lia-code-sample language-yaml"><code>steps:
npmExecuteScripts:
install: true
virtualFrameBuffer: false
dockerImage: 'cypress/browsers:node-20.18.0-chrome-130.0.6723.69-1-ff-131.0.3-edge-130.0.2849.52-1'
runScripts:
- 'test:ci'
sonarExecuteScan:
serverUrl: 'https://sonar.tools.sap'
stages:
Build:
npmExecuteScripts: true
sonarExecuteScan: true</code></pre><H3 id="toc-hId--1885554074">GitHub Actions example</H3><pre class="lia-code-sample language-yaml"><code>- name: Run tests with coverage
run: npm run test:ci
- name: SonarQube Scan
uses: sonarqube-scan-action@v1
with:
args: >
-Dsonar.projectKey=${{ env.PROJECT_KEY }}</code></pre><HR /><H2 id="toc-hId--1620480881">Generated Coverage Artifacts</H2><P>After running:</P><pre class="lia-code-sample language-bash"><code>npm run test:ci</code></pre><P> </P><P>you should see:</P><pre class="lia-code-sample language-bash"><code>coverage/
├── lcov.info
├── lcov-report/
│ └── index.html
└── cobertura-coverage.xml</code></pre><P> </P><H3 id="toc-hId--2110397393">What these files are used for</H3><UL><LI><CODE>lcov.info</CODE> → imported by SonarQube</LI><LI><CODE>lcov-report/</CODE> → human-readable HTML report for local inspection</LI><LI><CODE>cobertura-coverage.xml</CODE> → optional integration with other tools</LI></UL><HR /><H2 id="toc-hId--2013507891">How Coverage Appears in SonarQube</H2><P>After the scan, SonarQube usually shows two metrics that are especially important:</P><DIV class=""><DIV class="">Metric Meaning <TABLE><TBODY><TR><TD>Coverage on New Code</TD><TD>Coverage only for changed lines in the branch or PR</TD></TR><TR><TD>Overall Coverage</TD><TD>Coverage across the entire project</TD></TR></TBODY></TABLE></DIV></DIV><P>This distinction matters a lot.</P><P>A project can have:</P><UL><LI><STRONG>high coverage on new code</STRONG>, because the changed lines were properly tested</LI><LI><STRONG>low overall coverage</STRONG>, because legacy parts of the application still have poor test coverage</LI></UL><P>That is not a contradiction. It is normal SonarQube behavior.</P><HR /><H2 id="toc-hId-2084945900">Troubleshooting</H2><H3 id="toc-hId-1595029388">SonarQube shows 0% coverage</H3><P>Check the following first:</P><OL><LI><CODE>coverage/lcov.info</CODE> is generated successfully</LI><LI><CODE>sonar.javascript.lcov.reportPaths</CODE> points to the correct file</LI><LI><CODE>SF:</CODE> entries match the structure expected by <CODE>sonar.sources</CODE></LI></OL><P>Useful check:</P><pre class="lia-code-sample language-bash"><code>grep "^SF:" coverage/lcov.info</code></pre><HR /><H3 id="toc-hId-1398515883">Some files are missing from coverage</H3><P>This usually happens because only loaded files were instrumented during the browser run.</P><P>That is exactly why the normalization step is needed.</P><P>Without normalization, SonarQube may import only a partial coverage picture.</P><HR /><H3 id="toc-hId-1202002378">Coverage on new code is high, but overall coverage is low</H3><P>This is expected and does not necessarily indicate a problem.</P><P>It simply means:</P><UL><LI>your recent changes are well tested</LI><LI>older application code still lacks coverage</LI></UL><HR /><H3 id="toc-hId-1005488873">Warning: “Unable to process all coverage”</H3><P>This may appear when using <CODE>ui5-test-runner</CODE> with <CODE>--coverage-proxy</CODE>.</P><P>In practice, this warning means that not all source files could be discovered automatically during runtime instrumentation.</P><P>The custom normalization script compensates for this by adding the missing files manually.</P><HR /><H2 id="toc-hId-1102378375">Final Thoughts</H2><P>For me, the key goal of this implementation was not just to execute UI5 tests with coverage enabled, but to make the results <STRONG>usable and trustworthy inside SonarQube</STRONG>.</P><P>The most important lessons from this setup were:</P><UL><LI>generating LCOV is only the first step</LI><LI>path alignment between LCOV and <CODE>sonar.sources</CODE> is critical</LI><LI>browser-based runtime instrumentation does not guarantee full project visibility</LI><LI>normalizing missing files makes the SonarQube result much more accurate</LI></UL><P>With this approach in place, SAP UI5 projects can benefit from the same quality visibility that backend projects usually already have: clear coverage reports, PR metrics, and enforceable quality gates.</P><HR /><H2 id="toc-hId-905864870">References</H2><UL><LI><A href="https://github.com/ArnaudBuchholz/ui5-test-runner" target="_self" rel="nofollow noopener noreferrer">ui5-test-runner Documentation</A></LI><LI><A href="https://docs.sonarqube.org/latest/analysis/coverage/" target="_self" rel="nofollow noopener noreferrer">SonarQube JavaScript Coverage Documentation</A></LI><LI><A href="https://manpages.debian.org/unstable/lcov/geninfo.1.en.html" target="_self" rel="nofollow noopener noreferrer">LCOV Format Specification</A></LI></UL>2026-04-21T15:19:13.771000+02:00