https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/SAPUI5-blog-posts.xml SAP Community - SAPUI5 2025-01-17T21:02:09.085433+00:00 python-feedgen SAPUI5 blog posts in SAP Community https://community.sap.com/t5/technology-blogs-by-sap/change-of-numberformat-behavior-for-currencies-with-ui5-version-1-130/ba-p/13934199 Change of NumberFormat Behavior for Currencies with UI5 version 1.130 2024-11-27T09:00:00.018000+01:00 Viktor_Sperling https://community.sap.com/t5/user/viewprofilepage/user-id/1794862 <H2 id="toc-hId-1074775801"><SPAN>Intro</SPAN></H2><P><SPAN>With a recent change in&nbsp;<STRONG>UI5 version 1.130</STRONG>,&nbsp;we corrected the formatting of decimal places for currencies.</SPAN></P><P><SPAN>We now differentiate between two cases:</SPAN></P><UL><LI><SPAN><STRONG>Case 1:</STRONG>&nbsp;</SPAN> <SPAN>If the&nbsp;<FONT face="courier new,courier">style: "long"/"short"</FONT>&nbsp;format option is&nbsp;<STRONG>not</STRONG>&nbsp;set, and no&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;are provided in the&nbsp;</SPAN> <FONT face="courier new,courier"><SPAN>o</SPAN></FONT><SPAN><FONT face="courier new,courier">FormatOptions</FONT>&nbsp;of the&nbsp;<FONT face="courier new,courier"><A class="" title="sap.ui.core.format.NumberFormat.getCurrencyInstance" href="https://ui5.sap.com/#/api/sap.ui.core.format.NumberFormat%23methods/sap.ui.core.format.NumberFormat.getCurrencyInstance" target="_blank" rel="noopener noreferrer">sap.ui.core.format.NumberFormat.getCurrencyInstance</A> </FONT>API&nbsp;(either via the direct format option&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;or via currency customizing&nbsp;</SPAN> <SPAN>as specified by the format option&nbsp;</SPAN><FONT face="courier new,courier"><SPAN>customCurrencies</SPAN></FONT><SPAN>), the given value is formatted with the&nbsp;<FONT face="courier new,courier">decimals</FONT> </SPAN><SPAN>value defined by the CLDR standard.<BR /><BR /></SPAN></LI><LI><SPAN><STRONG>Case 2:</STRONG>&nbsp;</SPAN> <SPAN>If the&nbsp;</SPAN><FONT face="courier new,courier"><SPAN>style: "long"/"short"&nbsp;</SPAN></FONT><SPAN>format option is set, only the&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;explicitly set in the&nbsp;<FONT face="courier new,courier">oFormatOptions</FONT>&nbsp;of the&nbsp;<FONT face="courier new,courier"><A class="" title="sap.ui.core.format.NumberFormat.getCurrencyInstance" href="https://ui5.sap.com/#/api/sap.ui.core.format.NumberFormat%23methods/sap.ui.core.format.NumberFormat.getCurrencyInstance" target="_blank" rel="noopener noreferrer">sap.ui.core.format.NumberFormat.getCurrencyInstance</A> </FONT>API,&nbsp;are considered&nbsp;</SPAN> <SPAN>for the determination of the number of decimal places in the output.<BR />Any other source for the&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;attribute (i.e. your currency customizing or the CLDR) is not considered anymore.</SPAN></LI></UL><H2 id="toc-hId-878262296"><SPAN>Case 1: Format option&nbsp;<FONT face="courier new,courier">style: "long"/"short"</FONT>&nbsp;isn't set</SPAN></H2><H3 id="toc-hId-810831510"><SPAN>What's different?</SPAN></H3><P>Previously,<SPAN>&nbsp;</SPAN> <SPAN>applications may have defined currency formats, which relied on the</SPAN>&nbsp;<FONT face="courier new,courier"><SPAN>maxFractionDigits<FONT face="arial,helvetica,sans-serif">&nbsp;</FONT></SPAN></FONT>format option to specify the number of decimal places.<SPAN>&nbsp;</SPAN><SPAN>This is incorrect usage, as the&nbsp;<FONT face="courier new,courier">maxFractionDigits</FONT> </SPAN><SPAN>parameter is meant to define the maximum but not the actual number of decimals.</SPAN></P><H4 id="toc-hId-743400724"><SPAN>Example - Prior to the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123.456", "USD"] - Format options: {maxFractionDigits: 3} - Formatted result: "123.456 USD"</code></pre><P>&nbsp;</P><P><SPAN>With our change, this behavior has changed. Now the semantics of the&nbsp;<FONT face="courier new,courier">maxFractionDigits/minFractionDigits</FONT>&nbsp;format options is correctly interpreted for currency formats, namely as the maximum and minimum number of permitted decimals.</SPAN></P><H4 id="toc-hId-546887219"><SPAN>Example - After the chang:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123.456", "USD"] - Format options: {maxFractionDigits: 3} - Formatted result: "123.46 USD" (rounding is applied)</code></pre><P>&nbsp;</P><P><SPAN>For the&nbsp;<STRONG>en</STRONG> </SPAN><SPAN>&nbsp;locale, the formatted result has 2 decimal places:</SPAN></P><UL><LI>The<SPAN>&nbsp;<FONT face="courier new,courier">maxFractionDigits</FONT>&nbsp;define a&nbsp;<STRONG>maximum</STRONG>&nbsp;of&nbsp;<STRONG>3&nbsp;</STRONG>decimal places</SPAN></LI><LI><SPAN>The CLDR data defines the&nbsp;<STRONG>USD</STRONG>&nbsp;currency in the&nbsp;<STRONG>en</STRONG>&nbsp;locale with&nbsp;<STRONG>2</STRONG>&nbsp;decimal places</SPAN></LI></UL><P><SPAN><STRONG>As&nbsp;</STRONG> <STRONG>2 &lt; 3,</STRONG> <STRONG>&nbsp;this is the correct result. The output does not exceed the maximum number of decimal places in this format, and the currency is formatted according to the locale-specific standard.</STRONG> </SPAN></P><P><SPAN>This change also affects the formatting of currencies with fewer decimal places than expected by their CLDR configurations.</SPAN></P><H4 id="toc-hId-350373714"><SPAN>Example - Prior to the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123.4", "USD"] - Format options: {minFractionDigits: 0} - Formatted result: "123.4 USD"</code></pre><P>&nbsp;</P><P><SPAN>In the prior behavior, the number of decimal places remained the same if the number given contained more decimal places than defined by the&nbsp;<STRONG><FONT face="courier new,courier">minFractionDigits</FONT>&nbsp;</STRONG>option<STRONG>.</STRONG> </SPAN></P><H4 id="toc-hId-153860209"><SPAN>Example - After the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123.4", "USD"] - Format options: {minFractionDigits: 0} - Formatted result: "123.40 USD"</code></pre><P>&nbsp;</P><P><SPAN>With the new change in place, this is not the case anymore as the CLDR defines the number of decimal places for the&nbsp;<STRONG>USD</STRONG>&nbsp;currency in the given locale as&nbsp;<STRONG>2</STRONG>. Therefore, a zero is padded at the end.</SPAN></P><H2 id="toc-hId--300818734"><SPAN>Case 2: Format option&nbsp;<FONT face="courier new,courier">style: "long"/"short"</FONT>&nbsp;is set</SPAN></H2><P><SPAN>During the implementation of C</SPAN><SPAN>ase 1 it was discovered that the configuration of decimal places determined via any source (currency customizing or CLDR) is also applied to short or long formats of numbers (e.g. <FONT face="courier new,courier">1000.00 USD <FONT face="arial,helvetica,sans-serif">-&gt;</FONT> 1.00K USD</FONT>). This is unnecessary for such formats; therefore, we have now disabled the application of any currency customzing if the format option&nbsp;<FONT face="courier new,courier">style: "long"/"short"</FONT>&nbsp;is set.</SPAN></P><P><SPAN>The only remaining way to apply decimal place formatting to short or long formats of currencies is the&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;format option.</SPAN></P><H3 id="toc-hId--368249520"><SPAN>What's different?</SPAN></H3><P><SPAN>Previously, an application may have expected its currency short or long formats to have the number of decimal places as defined by the currency customizing for the currency, in its output format</SPAN><SPAN>; this may no longer be the case.</SPAN></P><H4 id="toc-hId--435680306"><SPAN>Example - Prior to the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123456", "USD"] - Format options: {style: 'short', maxFractionDigits: 0} - Formatted result: "123.00K USD"</code></pre><P>&nbsp;</P><P>This result is incorrect, as 2 zeros are padded at the end. The CLDR data determines the<SPAN>&nbsp;</SPAN><FONT face="courier new,courier"><SPAN>decimals</SPAN></FONT><SPAN>&nbsp;</SPAN>format option to <STRONG>2</STRONG> for <STRONG>USD.<SPAN>&nbsp;</SPAN> </STRONG><SPAN>While this is correct for a format without&nbsp;style&nbsp;short&nbsp;or&nbsp;long, formatted numbers with&nbsp;style&nbsp;often contain a metric prefix like&nbsp;<STRONG>“K”</STRONG>&nbsp;so that using the currency’s <FONT face="courier new,courier">decimals</FONT> is wrong.</SPAN></P><H4 id="toc-hId--1129910906"><SPAN>Example - After the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123456", "USD"] - Format options: {style: 'short', maxFractionDigits: 0} - Formatted result: "123K USD"</code></pre><P>&nbsp;</P><P>With our new change, no decimal places are displayed in the output format.</P><P>A similar behavior can be observed when<SPAN>&nbsp;</SPAN><FONT face="courier new,courier"><SPAN>customCurrencies<FONT face="arial,helvetica,sans-serif">&nbsp;</FONT></SPAN></FONT>are provided.</P><H4 id="toc-hId--1326424411"><SPAN>Example - Prior to the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123456", "USD"] - Format options: { style: 'short', maxFractionDigits: 0, customCurrencies: {USD: {decimals: 2}} } - Formatted result: "123.00K USD"</code></pre><P>&nbsp;</P><H4 id="toc-hId--1522937916"><SPAN>Example - After the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123456", "USD"] - Format options: { style: 'short', maxFractionDigits: 0, customCurrencies: {USD: {decimals: 2}} } - Formatted result: "123K USD"</code></pre><P>&nbsp;</P><P>It can be observed that the currency customizing is ignored if<SPAN>&nbsp;</SPAN><SPAN><FONT face="courier new,courier">style: "long"/"short"</FONT>&nbsp;is set.</SPAN></P><P><SPAN>To avoid any confusion, this rule does apply even if the currency amount is too small to contain a metric prefix (e.g.&nbsp;<STRONG>"K"</STRONG>) in its output format.</SPAN></P><H4 id="toc-hId--1719451421"><SPAN>Example - Prior to the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123", "USD"] - Format options: {style: 'short', maxFractionDigits: 0} - Formatted result: "123.00 USD"</code></pre><P>&nbsp;</P><P><SPAN>The given number too small to be formatted into a short format in the US locale.</SPAN></P><H4 id="toc-hId--1915964926"><SPAN>Example - After the change:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>- Values to be formatted: ["123", "USD"] - Format options: {style: 'short', maxFractionDigits: 0} - Formatted result: "123 USD"</code></pre><P>&nbsp;</P><P><SPAN>With the new change in place, the currency customizing (in this case via the CLDR) is not applied.</SPAN></P><H2 id="toc-hId--1525672417"><SPAN>What does that mean for tests and applications?</SPAN></H2><H3 id="toc-hId--2015588929"><SPAN>In case 1:</SPAN></H3><P><SPAN>The new behavior of tests and applications depends on the application setup. If the currency formats either use currency customizing where&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;are defined for all currencies or define a&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;format option for their binding, the behavior stays the same.</SPAN></P><P><SPAN>If, on the other hand, an application relies on the&nbsp;<FONT face="courier new,courier">maxFractionDigits</FONT>&nbsp;option to always determine the number of decimal places on its currency formats, this cannot be assured anymore. Only if&nbsp;<FONT face="courier new,courier"> <STRONG>maxFractionDigits<FONT face="arial,helvetica,sans-serif">&nbsp;</FONT></STRONG><STRONG>&lt;<FONT face="arial,helvetica,sans-serif">&nbsp;</FONT></STRONG></FONT></SPAN><SPAN><FONT face="courier new,courier"><STRONG>decimals</STRONG></FONT><STRONG>&nbsp;</STRONG>may<STRONG>&nbsp;</STRONG>the&nbsp;<FONT face="courier new,courier">maxFractionDigits</FONT>&nbsp;option still be used to format the output.</SPAN></P><P><SPAN>Thus, it is up to the application developer to decide, between one of the following alternatives:</SPAN></P><UL><LI><SPAN><STRONG>Alternative&nbsp;1</STRONG>&nbsp;(<EM>The application should rely on its currency customizing/the CLDR standard for the decimal places of currencies) -&nbsp;</EM>Any failing tests have to be adjusted.<BR /></SPAN></LI><LI><P><SPAN><STRONG>Alternative 2&nbsp;</STRONG>(<EM>The application should continue to determine the number of decimal places for currencies itself) -&nbsp;</EM>The application has to use the&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;format option instead of the&nbsp;<FONT face="courier new,courier">maxFractionDigits</FONT>&nbsp;option for that.</SPAN></P></LI></UL><H3 id="toc-hId-2082864862"><SPAN>In case 2:</SPAN></H3><P><SPAN><SPAN class="">With <FONT face="courier new,courier">style</FONT> set to <FONT face="courier new,courier">short</FONT> or <FONT face="courier new,courier">long</FONT>, the same alternatives exist as before</SPAN></SPAN><SPAN>, but with a slightly different semantic, and it is still up to the application developer to decide:</SPAN></P><UL><LI><SPAN><STRONG>Alternative&nbsp;1&nbsp;</STRONG>(<EM>The application shouldn't have the currency customizing/the CLDR standard affect its short or long&nbsp;formats by adding decimals) -</EM>&nbsp;Any failing tests have to be adjusted.<BR /></SPAN></LI><LI><P><SPAN><STRONG>Alternative 2</STRONG>&nbsp;(<EM>The application should continue to&nbsp;<STRONG>always</STRONG>&nbsp;display decimal places in its short or long formats) -&nbsp;</EM></SPAN><SPAN>The application has to use the&nbsp;<FONT face="courier new,courier">decimals</FONT>&nbsp;format option instead of the&nbsp;<FONT face="courier new,courier">maxFractionDigits</FONT>&nbsp;option for that.</SPAN></P></LI></UL><P><SPAN>For more information regarding the format options available for our<STRONG>&nbsp;<FONT face="courier new,courier">NumberFormat.getCurrencyInstance</FONT>&nbsp;</STRONG>API, see:&nbsp;<FONT face="courier new,courier"><A class="" title="sap.ui.core.format.NumberFormat.getCurrencyInstance" href="https://ui5.sap.com/#/api/sap.ui.core.format.NumberFormat%23methods/sap.ui.core.format.NumberFormat.getCurrencyInstance" target="_blank" rel="noopener noreferrer">sap.ui.core.format.NumberFormat.getCurrencyInstance</A> </FONT></SPAN></P> 2024-11-27T09:00:00.018000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/product-updates-for-sap-build-code-november-2024-edition/ba-p/13948533 Product Updates for SAP Build Code – November 2024 Edition 2024-11-28T08:36:58.413000+01:00 BirgitS https://community.sap.com/t5/user/viewprofilepage/user-id/41902 <P><SPAN>Dear SAP Community,</SPAN></P><P><SPAN>Welcome to our November release update! We're excited to present you many powerful new features. Whether you're a seasoned developer or just starting your journey, we have something for you.&nbsp;</SPAN><SPAN>This update features a range of exciting new capabilities, such as adding explanations to SQL statements for SAP HANA Cloud or an update to our Generative AI capabilities for MDK development.</SPAN></P><P><SPAN>Join us as we explore the details of what's new!</SPAN></P><P><STRONG><SPAN>&nbsp;</SPAN></STRONG></P><P><STRONG>SAP HANA Cloud SQL Statement Explanation</STRONG></P><P>The SAP HANA Database Explorer SQL Console in SAP Build Code offers a new feature for adding explanations to SQL statements for SAP HANA Cloud. The explanations can make it easier to understand complex or unfamiliar SQL queries.</P><P>The statement explanation feature is triggered by selecting an SQL statement in the SQL console and choosing “Explain SQL Statement using AI” from the menu.</P><P style=" text-align: center; "><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="ExplainStatement.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/195615i34C12C5F6D44BE07/image-size/large?v=v2&amp;px=999" role="button" title="ExplainStatement.png" alt="ExplainStatement.png" /></span><SPAN>Screenshot: Choosing “Explain SQL Statement using AI” from the Menu</SPAN></P><P>The explanations are added to a copy of the original statement into the SQL console. The copy that contains the explanations is delimited by “AI generated SQL query explanation begins/ends” block comments.</P><P style=" text-align: center; "><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="SQLQueryExplanations.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/195616i7DB683D9225BC835/image-size/large?v=v2&amp;px=999" role="button" title="SQLQueryExplanations.png" alt="SQLQueryExplanations.png" /></span><SPAN>Screenshot: AI Generated SQL Query Explanation</SPAN></P><P>As with all AI generated content the generated comments should be reviewed and checked for validity. If the comments are useful, the original statement may be discarded or combined with the comments as needed.</P><P><SPAN>&nbsp;</SPAN></P><P><STRONG>Generative AI Capabilities for MDK</STRONG></P><P>We are thrilled to announce an exciting update to our Generative AI capabilities for MDK (Mobile Development Kit) development. Previously, these capabilities were only available when a single project was opened at the folder level. We have now enhanced this functionality to support more scenarios. Our latest updates now enable you to use Generative AI features when working with multiple projects listed either in the Projects Explorer or at the workspace level.</P><P>For example, if you have multiple projects open in the Projects Explorer and want to generate a page in a specific project using the MDK page generation genie, it will now prompt you to select a service file from various service files in multiple projects and a page will be generated in that specific project. This enhancement provides greater flexibility and convenience when working with multiple projects in MDK development.</P><P style=" text-align: center; "><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="MDKPageGeneration.png" style="width: 461px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/195618i5852C4464D4CDDD9/image-size/large?v=v2&amp;px=999" role="button" title="MDKPageGeneration.png" alt="MDKPageGeneration.png" /></span></SPAN><SPAN>Screenshot: MDK page generation with Joule</SPAN></P><P>&nbsp;</P><P><STRONG>Further readings</STRONG></P><UL><LI>Announcing a New Guide: Deep Dive into SAPUI5 Apps on SAP BTP</LI></UL><P style=" padding-left : 30px; ">We are excited to share a new comprehensive guide crafted by our colleague Matthias Schmalz, offering profound technical insights into SAPUI5 applications running on the SAP Business Technology Platform (BTP). In this guide, Matthias delves into essential topics such as how to structure complex SAPUI5 applications to avoid common pitfalls, how multiple apps work with a shared reuse library and how to&nbsp;integrate business solutions as content providers into SAP Build Work Zone.</P><P style=" padding-left : 30px; ">For further details, dive into Matthias' guide <SPAN><A href="https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-1/ba-p/13923459" target="_blank">Designing UI5 Apps as Business Solution for SAP Build Work Zone</A></SPAN> and elevate your expertise in SAPUI5 development.</P><P style=" padding-left : 30px; ">&nbsp;</P><UL><LI><SPAN>Explore Our Recent SAP Fiori Tools Release </SPAN></LI></UL><P style=" padding-left : 30px; "><SPAN>For a deeper dive into the latest updates and features in SAP Fiori tools, be sure to check out the following blog post: <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-tools-2411-update-enhanced-full-stack-development-ai-integration/ba-p/13929515" target="_blank">SAP Fiori Tools 2411 Update: Enhanced Full-Stack Development, AI Integration, and More Open Source</A>. This post provides a comprehensive overview of the new features and improvements that combine frontend and backend development, broaden AI-driven functionalities, and further the integration of open-source technologies.</SPAN></P><P style=" padding-left : 30px; ">&nbsp;</P><UL><LI><SPAN>&nbsp;</SPAN>How to Upgrade Your Existing Standalone Service Plans</LI></UL><P style=" padding-left : 30px; ">SAP Build Code offers different types of service plans in SAP BTP: trial, free and standard. For the initial setup, a booster helps you set up SAP Build Code for the plan you want to use. But what if you already use an existing standalone service plan and want to upgrade to one of the SAP Build Code service plans?</P><P style=" padding-left : 30px; ">We created the following group: <A href="https://developers.sap.com/group.sap-btp-update-current-build-code.html" target="_blank" rel="noopener noreferrer">Update from Current Service Plan to Build-Code Service Plan</A>. This group consists of tutorials that guide you step by step through the upgrade process:</P><UL class="lia-list-style-type-circle"><LI><A href="https://developers.sap.com/tutorials/btp-build-code-migration-plans-add.html" target="_blank" rel="noopener noreferrer">Add SAP Build Code standard (Application) plan</A></LI><LI><A href="https://developers.sap.com/tutorials/btp-build-code-migration-plans-subscribe.html" target="_blank" rel="noopener noreferrer">Create an SAP Build Code Standard (Application) Subscription</A></LI><LI><A href="https://developers.sap.com/tutorials/btp-build-code-migration-plans-mobile-service-build-code-plan.html" target="_blank" rel="noopener noreferrer">Add build-code service plan</A></LI><LI><A href="https://developers.sap.com/tutorials/btp-build-code-migration-plans-mobile-service-plan-update.html" target="_blank" rel="noopener noreferrer">Update Service Plan</A></LI></UL><P style=" padding-left : 30px; ">Our <A href="https://help.sap.com/docs/build_code/d0d8f5bfc3d640478854e6f4e7c7584a/d501fb669447478cbcd07a0b7b7ca4c0.html" target="_blank" rel="noopener noreferrer">help documentation</A> provides you a list of different current and target service plans and supported migration scenarios.</P><P style=" padding-left : 30px; ">&nbsp;</P><UL><LI>Webinar Series What's New in SAP HANA 2.0 SPS 08</LI></UL><P style=" padding-left : 30px; ">Interested in discovering the latest innovations in SAP HANA 2.0 SPS 08? Then join our "<A href="https://community.sap.com/t5/technology-blogs-by-sap/what-s-new-in-sap-hana-2-0-sps-08/ba-p/13941640" target="_blank">What's New in SAP HANA 2.0 SPS 08</A>" webinar series! This series is divided into seven captivating sessions, each filled with insights from over a dozen experts straight from our SAP HANA &amp; Database Product Management team. Dive deep into key updates and features while gaining practical industry knowledge.</P><P><SPAN>&nbsp;</SPAN></P><P>For further information on new features, please check our roadmaps: <SPAN><A href="https://roadmaps.sap.com/board?PRODUCT=73555000100800004515&amp;range=2024Q4-2025Q3#Q4%202024" target="_blank" rel="noopener noreferrer">roadmap for SAP Build Code</A></SPAN>, <SPAN><A href="https://roadmaps.sap.com/board?PRODUCT=73554900100800001361" target="_blank" rel="noopener noreferrer">SAPUI5 Road Map</A></SPAN>. And have a look at <SPAN><A href="https://help.sap.com/whats-new/cf0cb2cb149647329b5d02aa96303f56?Component=Cloud%20Logging%3BCloud%20Transport%20Management%3BContinuous%20Integration%20%26%20Delivery%3BDocument%20Management%20Service%3BMobile%20Services%3BSAP%20Alert%20Notification%20Service%3BSAP%20BTP,%20Cloud%20Foundry%20Runtime%3BSAP%20Build%3BSAP%20Business%20Application%20Studio&amp;locale=en-US&amp;version=Cloud" target="_blank" rel="noopener noreferrer">What's New in SAP Build Code</A></SPAN>, the <SPAN><A href="http://help.sap.com/disclaimer?site=https://help.sap.com/whats-new/67f60363b57f4ac0b23efd17fa192d60" target="_blank" rel="noopener noreferrer">What's New Viewer for SAPUI5</A></SPAN> and the <SPAN><A href="https://cap.cloud.sap/docs/releases/" target="_blank" rel="noopener nofollow noreferrer">SAP Cloud Application Programming Model Release Notes</A></SPAN><STRONG>. </STRONG><STRONG>If you want to stay up-to-date with news, learning resources, and product and strategy updates for SAP Build Code:&nbsp;</STRONG>follow our&nbsp;<SPAN><A href="https://community.sap.com/t5/c-khhcw49343/SAP%2520Build%2520Code/pd-p/73555000100800004372" target="_blank">tag</A></SPAN>.</P><P>We look forward to seeing how you use these new capabilities to create innovative solutions and drive your projects forward. Stay tuned for more updates and happy coding! <span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span></P> 2024-11-28T08:36:58.413000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/advent-of-code-2024-exploring-ui5/ba-p/13953453 🎄💻Advent of Code 2024: Exploring UI5 2024-12-02T20:34:09.228000+01:00 yogananda https://community.sap.com/t5/user/viewprofilepage/user-id/75 <P><SPAN>The Advent of Co</SPAN>de (AoC) is an annual event that excites the programming SAP community every December. It's a series of daily coding challenges that run from December 1st to December 25th, offering a fun and engaging way to improve your coding skills. This year, let's dive into how you can tackle these challenges using UI5, a powerful framework for building enterprise-ready web applications.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="GYx_PTMWEAQvy5P.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/197567i13AF5F659B1C4347/image-size/large?v=v2&amp;px=999" role="button" title="GYx_PTMWEAQvy5P.jpg" alt="GYx_PTMWEAQvy5P.jpg" /></span></P><P><EM>Image source : Google Images</EM></P><H3 id="toc-hId-1205678524">Getting Started with UI5</H3><P>To get started with UI5 for Advent of Code, you'll need to set up your development environment. Here are the basic steps:</P><OL><LI>Install Node.js and npm: UI5 requires Node.js and npm for development. You can download and install them from the official Node.js website.</LI><LI>Set Up UI5 CLI: The UI5 Command Line Interface (CLI) is a powerful tool that helps you manage your UI5 projects. Install it using npm:</LI></OL><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>npm install --global @ui5/cli npm install --global yo npm install --global create-easy-ui5</code></pre><P>&nbsp;</P><P>This simple example demonstrates how UI5 can be used to create interactive solutions for Advent of Code challenges. By leveraging UI5's powerful features, you can build robust and visually appealing applications to solve even the most complex problems.<BR /><BR /><STRONG>Github repo for AoC 2024</STRONG><BR /><A href="https://github.com/yogananda-muthaiah/adventofcode2024/tree/main" target="_blank" rel="noopener nofollow noreferrer">https://github.com/yogananda-muthaiah/adventofcode2024</A></P><H2 id="toc-hId-880082300">SAP UI5 Components</H2><P><A href="https://ui5.sap.com/#/controls" target="_blank" rel="noopener noreferrer">https://ui5.sap.com/#/controls</A></P><H2 id="toc-hId-683568795">SAP UI5 Icons Explorer</H2><P><A href="https://ui5.sap.com/test-resources/sap/m/demokit/iconExplorer/webapp/index.html" target="_blank" rel="noopener noreferrer">https://ui5.sap.com/test-resources/sap/m/demokit/iconExplorer/webapp/index.html</A></P><H2 id="toc-hId-487055290"><SPAN>Live Editor</SPAN></H2><P><SPAN><A href="https://ui5.sap.com/#/liveEditor" target="_blank" rel="noopener noreferrer">https://ui5.sap.com/#/liveEditor</A><BR /></SPAN></P><H2 id="toc-hId-290541785"><SPAN>UI5 Tooling</SPAN></H2><P><SPAN><A href="https://sap.github.io/ui5-tooling/stable/" target="_blank" rel="noopener nofollow noreferrer">https://sap.github.io/ui5-tooling/stable/</A><BR /></SPAN></P><H2 id="toc-hId-94028280"><SPAN>UI5 Linter</SPAN></H2><P><SPAN><A href="https://github.com/SAP/ui5-linter" target="_blank" rel="noopener nofollow noreferrer">https://github.com/SAP/ui5-linter</A><BR /></SPAN></P><H4 id="toc-hId-155680213">Conclusion</H4><P>Advent of Code is a fantastic opportunity to sharpen your coding skills and have fun with the global programming community. Using UI5, you can enhance your solutions with rich UI components and efficient architecture. So, get ready to code, learn, and enjoy the Advent of Code 2024 with UI5!</P><P>&nbsp;</P> 2024-12-02T20:34:09.228000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/deprecation-of-karma-ui5-plugin/ba-p/13954060 Deprecation of karma-ui5 plugin 2024-12-04T05:27:35.113000+01:00 OliverGraeff https://community.sap.com/t5/user/viewprofilepage/user-id/4124 <P style=" text-align : left; ">SAPUI5/OpenUI5 provides several testing options, like unit and integration tests, which are summarized in <A href="https://ui5.sap.com/#/topic/7cdee404cac441888539ed7bfe076e57" target="_self" rel="noopener noreferrer">UI5 Testing:</A></P><P style=" text-align: center; "><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="UI5 testing.png" style="width: 928px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/197816i3671F4F2B937ED9C/image-size/large?v=v2&amp;px=999" role="button" title="UI5 testing.png" alt="UI5 testing.png" /></span><SPAN>Picture 1: Testing UI5 applications</SPAN></P><P>To ensure that code is tested thoroughly before it is included in a productive app, using a test runner is best practice to automate the regular execution of tests. The test runner can be included in a project setup to be called whenever code changes are submitted.</P><P>In this context, the UI5 team is now faced with a new situation: Handling current problems with browsers would require an update of the Karma test runner, which is deprecated.</P><P style=" text-align: center; "><STRONG>The Karma test runner is <A href="https://github.com/karma-runner/karma#karma-is-deprecated-and-is-not-accepting-new-features-or-general-bug-fixes" target="_self" rel="nofollow noopener noreferrer">deprecated</A> since April 2023. Now we have to also deprecate <A href="https://github.com/SAP/karma-ui5" target="_self" rel="nofollow noopener noreferrer">karma-ui5</A>.</STRONG></P><P>(Please note that while karma-ui5 is deprecated and does not receive further updates, it can still be used as long as it fulfils your needs.)</P><P>UI5 does not provide features for a specific other test runner, but rather aims for an agnostic approach. To execute functional and integration tests you may use a test runner of your choice with the respective configuration for QUnit and OPA5 tests.&nbsp;In <A href="https://bestofui5.org/#/packages?tokens=testing:tag" target="_blank" rel="noopener nofollow noreferrer">UI5 community projects</A> we listed alternative test runners, e.g.</P><UL><LI><A href="https://github.com/ArnaudBuchholz/ui5-test-runner" target="_blank" rel="noopener nofollow noreferrer">ui5-test-runner</A>, executing tests in parallel. See more details in <A href="https://www.youtube.com/live/kxmmdy1tho4" target="_blank" rel="noopener nofollow noreferrer">this Devtoberfest 2023 session</A>.</LI><LI><A href="https://github.com/mauriciolauffer/wdio-qunit-service" target="_blank" rel="noopener nofollow noreferrer">wdio-qunit-service</A><SPAN>, a WebdriverIO plugin</SPAN></LI></UL><P>You might also be interested in <A href="https://openui5.org/events/#id=ui5ers-44" target="_self" rel="nofollow noopener noreferrer">this UI5ers live webcast</A> which discusses test runners.</P> 2024-12-04T05:27:35.113000+01:00 https://community.sap.com/t5/application-development-blog-posts/sap-developer-news-december-5th-2024/ba-p/13956277 SAP Developer News, December 5th, 2024 2024-12-05T21:10:00.038000+01:00 thomas_jung https://community.sap.com/t5/user/viewprofilepage/user-id/139 <P><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FJrxvwrYwlCo&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DJrxvwrYwlCo&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2FJrxvwrYwlCo%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="400" height="225" scrolling="no" title="YouTube embed" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><STRONG>Podcast</STRONG>: <A href="https://podcast.opensap.info/sap-developers/2024/12/05/sap-developer-news-december-5th-2024/" target="_blank" rel="nofollow noopener noreferrer">https://podcast.opensap.info/sap-developers/2024/12/05/sap-developer-news-december-5th-2024/</A></P><H3 id="toc-hId-1205766041">DESCRIPTION</H3><P><STRONG>Orchestration service of Generative AI Hub</STRONG></P><UL><LI>Learning Journey on Generative AI Hub: <A href="https://learning.sap.com/learning-journeys/solving-your-business-problems-using-prompts-and-llms-in-sap-s-generative-ai-hub/using-generative-ai-hub-sdk-to-leverage-power-of-llms" target="_blank" rel="noopener noreferrer">https://learning.sap.com/learning-journeys/solving-your-business-problems-using-prompts-and-llms-in-sap-s-generative-ai-hub/using-generative-ai-hub-sdk-to-leverage-power-of-llms</A></LI><LI>SAP Help Orchestration service of Generative AI Hub on SAP AI Core: <A href="https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/orchestration-workflow" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/orchestration-workflow</A></LI></UL><P><STRONG>New UI for SAP Build Apps</STRONG></P><UL><LI>Daniel’s blog on new UI: <A href="https://community.sap.com/t5/sap-builders-blog-posts/review-new-layout-features-for-sap-build-apps/ba-p/13933240" target="_blank">https://community.sap.com/t5/sap-builders-blog-posts/review-new-layout-features-for-sap-build-apps/ba-p/13933240</A></LI></UL><P><STRONG>Updated integration architecture guide and API Management</STRONG></P><UL><LI>Integration architecture guide: Updated version available now: <A href="https://community.sap.com/t5/technology-blogs-by-sap/integration-architecture-guide-updated-version-available-now/ba-p/13930016" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/integration-architecture-guide-updated-version-available-now/ba-p/13930016</A></LI><LI>Please share your experience - new API Management survey: <A href="https://community.sap.com/t5/technology-blogs-by-sap/please-share-your-experience-new-api-management-survey/ba-p/13950848" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/please-share-your-experience-new-api-management-survey/ba-p/13950848</A></LI></UL><P><STRONG>karma-ui5 plugin deprecation and upcoming UI5 &amp; CAP events</STRONG></P><UL><LI>karma-ui5 deprecation blog post <A href="https://community.sap.com/t5/technology-blogs-by-sap/deprecation-of-karma-ui5-plugin/ba-p/13954060" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/deprecation-of-karma-ui5-plugin/ba-p/13954060</A></LI><LI>UI5ers Live 12 December <A href="https://www.linkedin.com/events/ui5erslive-december20247268259526246645760/about/" target="_blank" rel="nofollow noopener noreferrer">https://www.linkedin.com/events/ui5erslive-december20247268259526246645760/about/</A></LI><LI>CAP Customer Roundtable 12 December <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-cloud-application-programming-model-eighth-customer-roundtable/ba-p/13951006" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-cloud-application-programming-model-eighth-customer-roundtable/ba-p/13951006</A></LI></UL><H3 id="toc-hId-1009252536">CHAPTER TITLES</H3><P>0:00 Intro</P><P>0:10 Orchestration service of Generative AI Hub</P><P>1:03 New UI for SAP Build Apps</P><P>2:10 Updated integration architecture guide and API Management</P><P>3:00 karma-ui5 plugin deprecation and upcoming UI5 &amp; CAP events</P><H3 id="toc-hId-812739031">Transcription</H3><P><STRONG>[Intro]</STRONG> This is the SAP Developer News for December 5th, 2024.</P><P><STRONG>[Nora]</STRONG> There's a lot of talk about the integration of Microsoft Co-pilot and Joule here at UKISUG, but if you want to try out and build your own customized AI use cases, then you should try out Generative AI Hub. We had a session on it on Sunday, where we actually used the orchestration service and the JavaScript SDK and the Python SDK to build our own AI use cases. And what I love most about the orchestration service is that you can use the same code base for all the available models that we have, and you just have to change the model name parameter to try out the different models and compare the results which I think is awesome. We also have a lot of other features in the orchestration service for example the content filtering and the data masking the prompt templating and obviously the grounding feature which you need if you want to build your own RAG use cases and the grounding feature is already available in the API in the next coming week it's also going to be available via the SDKs and I'm super excited to try it out myself let me know what you think once you try it out.</P><P><STRONG>[Daniel]</STRONG> SAP Build Apps updated its design time UI to put front and center the things that you use most often and to hide the things that you use less often or even just once during your project development. So the first thing they did is to update the main menu. So you have just the main parts of building an application, which is the UI, the variables, which I consider part of the logic, and connecting to data resources. Then they moved the preview and build or now publish buttons in the upper right in a place where most IDEs would put them. And finally, they created a much easier way to handle managing pages, creating new pages or navigating to those pages. And that way you don't have to go into the page UI. I've written a blog that gives a review of all the changes, some tips on using them or finding what you need, though, and also my opinion on some of the features and perhaps some of the features I would like to see in the future. So check out the blog, and I'll put the link in the description.</P><P><STRONG>[Antonio]</STRONG> Hola, SAP developers. We're here at the UKISUG Connect event in Birmingham, and I have some quick leads to share with you. First, the Integration Architecture Guide was recently updated. It is structured according to the concepts of the Integration Solution Advisor Methodology. And it provides you guidelines about all things integration, including process integration, event-driven integration, API integrations, data integration, and user integration. So make sure to check it out. Also, we want your feedback regarding the API management capability. There is a new server available and we want you to learn more about how you're implementing and benefiting from the capability, or even why you're not using API management. So, we're looking forward to hearing back from you.</P><P><STRONG>[DJ]</STRONG> I've just got time for some news items on count. And UI5, first UI5. As some of you already may be aware, the Karma UI5 plugin is deprecated. This follows the deprecation of the Karma test runner itself upon which the plugin is based. But don't despair, there are plenty of other testing options available, including the UI5 test runner. And also, there's an event next week on Thursday the 12th of December, UI5ers Live, where this deprecation is discussed along with alternative options. And talking of next week, Thursday the 12th of December, there's a second event that day for CAP developers. It's another CAP customer round table with lots of news and updates from the CAP team and discussion of topics from the community. That's you. So check out Oliver's blog post on the deprecation and also the event pages. Links, as always, are in the description.</P> 2024-12-05T21:10:00.038000+01:00 https://community.sap.com/t5/technology-blogs-by-members/introducing-deep-export-for-multi-level-data-extraction-in-ui5-and-fiori/ba-p/13958798 Introducing Deep Export for Multi-Level Data Extraction in UI5 and Fiori Elements 2024-12-09T10:59:37.060000+01:00 Marian_Zeis https://community.sap.com/t5/user/viewprofilepage/user-id/61 <H2 id="toc-hId-1076747772">1. Why Did I Create That?</H2><P>When working with UI5 and Fiori Elements applications, the default options for exporting data to a spreadsheet may not be flexible enough for your needs. You might require special formatting, custom logic, or the ability to handle complex datasets that include multiple related entities. This is where the <A href="https://spreadsheet-importer.com/" target="_self" rel="nofollow noopener noreferrer">Spreadsheet Importer</A> comes in. It’s a UI5-based solution that enhances your data handling capabilities beyond standard exports, allowing you to retrieve and organize extensive multi-level data structures with ease.</P><P>For example, consider a scenario with Orders, their associated OrderItems, and possibly ShippingInfos. With the Spreadsheet Importer’s deep export feature, you can pull all of this interconnected data in one go. This comprehensive approach makes it simple to review, refine, and then reimport updates, delivering a more efficient and controlled data management workflow.</P><H2 id="toc-hId-880234267">2. How Do You Use It?</H2><P>Using the deep download feature is straightforward. All configuration and usage details are documented here:</P><P><A href="https://docs.spreadsheet-importer.com/pages/spreadsheetdownload/" target="_blank" rel="noopener nofollow noreferrer">https://docs.spreadsheet-importer.com/pages/spreadsheetdownload/</A></P><P>In essence, you enable the deep export configuration in the component data and define how many levels of sub-entities you want to include, along with which columns and properties should appear in your exported spreadsheet.</P><P><STRONG>Note:</STRONG> This new feature is experimental and currently only available for OData V4. If you deep download data, the OData Service must support $expand.</P><P>In a Fiori Elements List Report Extension, the code can look like this:</P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>this.spreadsheetUpload = await this.editFlow .getView() .getController() .getAppComponent() .createComponent({ usage: 'spreadsheetImporter', async: true, componentData: { context: this, action: 'UPDATE', createActiveEntity: true, i18nModel: this.getModel('i18n'), debug: true, showDownloadButton: true, deepDownloadConfig: { deepLevel: 1, deepExport: false, addKeysToExport: true, showOptions: true, filename: 'Orders123', columns: { OrderNo: { order: 1, }, buyer: { order: 3, }, Items: { quantity: { order: 2, }, title: { order: 4, }, }, Shipping: { address: { order: 5, }, }, }, }, }, }); this.spreadsheetUpload.triggerDownloadSpreadsheet();</code></pre><P>&nbsp;</P><P>This example shows the configuration options available:</P><UL><LI><STRONG>deepLevel:</STRONG> How many levels should the export go into the entities? If the value is ‘0’, only the main entity is exported.</LI><LI><STRONG>deepExport:</STRONG> This activates or deactivates the deep export. When switched off, only the main entity is exported.</LI><LI><STRONG>addKeysToExport:</STRONG> Normally, fields marked as ‘hidden’ (like GUIDs) are not included. With this setting, they are included, which is also important for a later re-import when data is updated.</LI><LI><STRONG>filename:</STRONG> The name of the Excel file when it is exported.</LI><LI><STRONG>columns:</STRONG> An object that determines which columns are exported. In debug mode, all possible columns are logged in the console.</LI><LI><STRONG>showOptions:</STRONG> Allows changing some settings via a dialog when the export is triggered.</LI></UL><P>Excel File can then look like this:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Marian_Zeis_0-1733739686011.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199876i0ED39326C8BAE932/image-size/medium?v=v2&amp;px=400" role="button" title="Marian_Zeis_0-1733739686011.png" alt="Marian_Zeis_0-1733739686011.png" /></span></P><H3 id="toc-hId-812803481">2.1 How to Trigger the Export</H3><H4 id="toc-hId-745372695">2.1.2. Directly in Code</H4><P>You can easily trigger the export directly in code by using the triggerDownloadSpreadsheet method. With this method, it’s also possible to pass other configuration parameters. The settings dialog can be displayed here as well.</P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>this.spreadsheetUpload.triggerDownloadSpreadsheet({ deepLevel: 1, deepExport: true, addKeysToExport: true, showOptions: true, filename: 'Orders_TEST', columns: { OrderNo: { order: 1, }, buyer: { order: 3, }, Items: { quantity: { order: 2, }, } }, });</code></pre><P>&nbsp;</P><H4 id="toc-hId-548859190">2.1.2 In the Spreadsheet Upload Dialog</H4><P>With the ‘<EM><STRONG>showDownloadButton</STRONG></EM>’ option, the export button is displayed directly in the upload dialog. You can try this in the Live Demo for my OData V4 Fiori Elements List Report Sample:</P><P><A href="https://livedemo.spreadsheet-importer.com/launchpad.html?sap-language=EN#ordersv4fe-120" target="_blank" rel="noopener nofollow noreferrer">https://livedemo.spreadsheet-importer.com/launchpad.html?sap-language=EN#ordersv4fe-120</A></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Marian_Zeis_0-1733737276018.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199860i77EB0AD1271A1502/image-size/medium?v=v2&amp;px=400" role="button" title="Marian_Zeis_0-1733737276018.png" alt="Marian_Zeis_0-1733737276018.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Marian_Zeis_1-1733737278680.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199861i0251EE506C3880CE/image-size/medium?v=v2&amp;px=400" role="button" title="Marian_Zeis_1-1733737278680.png" alt="Marian_Zeis_1-1733737278680.png" /></span></P><H4 id="toc-hId-352345685">2.1.3. Without Code in the XML View as a Button</H4><P>For uploading, you can also integrate the button directly into the XML view without any JavaScript code. This is also available for exporting and could then look like this:</P><P>&nbsp;</P><pre class="lia-code-sample language-markup"><code>&lt;core:ComponentContainer id="test2" width="100%" usage="spreadsheetImporter" propagateModel="true" async="true" settings="{ componentContainerData:{uploadButtonPress:'uploadButtonPress',buttonText:'Excel Download with Dialog',buttonId:'downloadButtonDialog',buttonIcon:'sap-icon://download',downloadButton:true}, deepDownloadConfig:{ deepLevel: 2, deepExport: true, addKeysToExport: true, showOptions: true, filename: 'Orders_Dialog', columns : { 'OrderNo':{ 'order': 1 }, 'buyer': { 'order': 3 }, 'Items': { 'quantity' : { 'order': 2 } }, 'Shipping': { 'address' : { 'order': 5 } } } } }" /&gt;</code></pre><P>&nbsp;</P><P>You can check out the sample in my live demo here:</P><P><A href="https://livedemo.spreadsheet-importer.com/launchpad.html?sap-language=EN#ordersv4freestyle-120" target="_blank" rel="noopener nofollow noreferrer">https://livedemo.spreadsheet-importer.com/launchpad.html?sap-language=EN#ordersv4freestyle-120</A></P><P>The code for this app can be found <A href="https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter/blob/main/examples/packages/ordersv4freestyle/webapp/view/MainView.view.xml" target="_self" rel="nofollow noopener noreferrer">here</A>.<BR />The Documentation for it is <A href="https://docs.spreadsheet-importer.com/pages/Configuration/#configuration" target="_self" rel="nofollow noopener noreferrer">here</A>.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Marian_Zeis_2-1733737317297.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199862i29930049FA5A1A4E/image-size/medium?v=v2&amp;px=400" role="button" title="Marian_Zeis_2-1733737317297.png" alt="Marian_Zeis_2-1733737317297.png" /></span></P><H2 id="toc-hId--102333258">3. Events for Interjecting into the Process</H2><P>You can manipulate the data at various steps. Two events give you the opportunity to influence the final result.</P><H3 id="toc-hId--169764044">3.1. Event beforeDownloadFileProcessing</H3><P>This event is fired before the data is converted to a spreadsheet file. Use this event to manipulate the data before conversion. You can change the data parameter of the event directly, as this is a reference.</P><P>Documentation: <A href="https://docs.spreadsheet-importer.com/pages/Events/#event-beforedownloadfileprocessing" target="_blank" rel="noopener nofollow noreferrer">https://docs.spreadsheet-importer.com/pages/Events/#event-beforedownloadfileprocessing</A></P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>onDownload: async function () { // init your spreadsheet upload component this.spreadsheetUpload.attachBeforeDownloadFileProcessing(this.onBeforeDownloadFileProcessing, this); this.spreadsheetUpload.triggerDownloadSpreadsheet(); }, onBeforeDownloadFileProcessing: function (event) { const data = event.getParameters().data; // change buyer of first row of the root entity data.$XYZData[0].buyer = "Customer 123"; // change quantity of first row of the Items entity data.Items.$XYZData[0].quantity = 4 }</code></pre><P>&nbsp;</P><H3 id="toc-hId--366277549">3.2. Event beforeDownloadFileExport</H3><P>This event is fired just before the file is downloaded. Use this event to manipulate the filename or other parameters before the file is downloaded.</P><P>The great flexibility here is that you can use the <A href="https://docs.sheetjs.com/docs/csf/book/" target="_self" rel="nofollow noopener noreferrer">workbook object</A> of SheetJS and all possible APIs before it is downloaded.</P><P>Documentation: <A href="https://docs.spreadsheet-importer.com/pages/Events/#event-beforedownloadfileexport" target="_blank" rel="noopener nofollow noreferrer">https://docs.spreadsheet-importer.com/pages/Events/#event-beforedownloadfileexport</A></P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>onDownload: async function () { // init your spreadsheet upload component this.spreadsheetUpload.attachBeforeDownloadFileExport(this.onBeforeDownloadFileExport, this); this.spreadsheetUpload.triggerDownloadSpreadsheet(); }, onBeforeDownloadFileExport: function (event) { const workbook = event.getParameters().workbook; event.getParameters().filename = filename + "_modified"; }</code></pre><P>&nbsp;</P><H2 id="toc-hId--691873773">4. Try It in the Live Demo</H2><P>If you want to see the deep download feature in action before integrating it into your own application, you can test it out in our live demo environment:</P><P><A href="https://livedemo.spreadsheet-importer.com/launchpad.html#ordersv4freestyle-120" target="_blank" rel="noopener nofollow noreferrer">https://livedemo.spreadsheet-importer.com/launchpad.html#ordersv4freestyle-120</A></P><P>This demo showcases how to trigger a deep export, configure columns, and retrieve deeply nested data structures from the backend. This is an OData V4 Freestyle App with UI5 Version 1.120.</P><H2 id="toc-hId--541132921">5. How Does It Work Internally?</H2><P>Under the hood, the deep download feature relies on OData V4’s $expand capabilities to fetch nested entities in a single request. The Spreadsheet Importer constructs a metadata model that maps out all related entities and their navigation properties. It then dynamically builds a set of expands to retrieve all linked data efficiently.</P><P>To dive deeper into the technical details and understand the internals, please visit:</P><P><A href="https://docs.spreadsheet-importer.com/pages/Development/SpreadsheetDownload/" target="_blank" rel="noopener nofollow noreferrer">https://docs.spreadsheet-importer.com/pages/Development/SpreadsheetDownload/</A></P><P>There you will find comprehensive documentation on metadata handling, batch fetching, and the steps involved in generating the final spreadsheet.</P><H2 id="toc-hId--737646426">6. e2e Tests</H2><P>Of course, no new feature can be developed without testing.<BR />The reliable <A href="https://ui5-community.github.io/wdi5/#/" target="_self" rel="nofollow noopener noreferrer">wdi5</A> comes into play again for this, and it can also be used to simply check the download of Excel files.&nbsp;Currently, only UI5 version 1.120 is being tested. Other versions will follow.<BR />Various scenarios are tested, including starting from exporting the code and from the button in the XML view.</P><P>Here is a run of the test:&nbsp;<A href="https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter/actions/runs/12206743460/job/34056849369" target="_blank" rel="noopener nofollow noreferrer">https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter/actions/runs/12206743460/job/34056849369</A>&nbsp;<BR />Here is the test file for wdi5 that runs from now on every PR:&nbsp;<A href="https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter/blob/main/examples/test/specs/download/DownloadSpreadsheetListReport.test.js" target="_blank" rel="noopener nofollow noreferrer">https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter/blob/main/examples/test/specs/download/DownloadSpreadsheetListReport.test.js</A>&nbsp;</P><H2 id="toc-hId--934159931">7. What Also Happened in the Last Versions (Since Version 1.0)</H2><P>The Spreadsheet Importer has been actively developed and improved over time. Since the release of version 1.0, several changes and enhancements have been introduced:</P><UL><LI><STRONG>New Configuration <A href="https://docs.spreadsheet-importer.com/pages/Configuration/#excludecolumns" target="_self" rel="nofollow noopener noreferrer">excludeColumns</A>:</STRONG> You can specify columns to exclude from the import and the template instead of specifying all columns you want.</LI><LI><STRONG>New event <A href="https://docs.spreadsheet-importer.com/pages/Events/#event-prefileprocessing" target="_self" rel="nofollow noopener noreferrer">preFileProcessing</A>:</STRONG> An event fired right after the file is uploaded to the app and before further processing.</LI><LI><STRONG>New LLM-translated language:</STRONG> Dutch</LI><LI><STRONG>Drag &amp; Drop support:</STRONG> Easily drag your spreadsheet file onto the upload dialog.</LI><LI><STRONG><A href="https://docs.spreadsheet-importer.com/pages/Configuration/#i18nmodel" target="_self" rel="nofollow noopener noreferrer">Custom i18n text overwrites</A>:</STRONG> All translated texts can now be overwritten by providing your own i18n model, allowing more flexibility in localization.</LI></UL><P>For the full list of changes, please refer to our detailed <A href="https://docs.spreadsheet-importer.com/pages/CHANGELOGSPREADSHEETIMPORTER/" target="_self" rel="nofollow noopener noreferrer">Changelog</A>.</P><H2 id="toc-hId--1130673436">8. What Is Happening in the Future?</H2><P>The journey doesn’t end here. Future improvements include:</P><UL><LI><STRONG>Support OData V2 for Deep Export:</STRONG> Currently, only OData V4 is supported.</LI><LI><STRONG>Update Support:</STRONG> Currently, only Create is possible via the spreadsheet importer. We plan to enable full Update capabilities so you can round-trip your data effortlessly. The data export is a prerequisite for making updates easily possible.</LI><LI><STRONG>Support Deep Insert:</STRONG> This is a major challenge, but one of my main goals is to integrate this functionality.</LI></UL><P>Stay tuned for upcoming releases.</P><H3 id="toc-hId--1620589948">Previous Announcements &amp; Background</H3><P>For those who missed it, we celebrated the version 1.0 release of the UI5 Spreadsheet Importer earlier this year. The response has been tremendous, and we extend our thanks to everyone who contributed, tested, and provided valuable feedback.</P><P>If you have any questions and suggestions, feel free to reach out at <A href="mailto:marian@marianzeis.de" target="_blank" rel="noopener nofollow noreferrer">marian@marianzeis.de</A>.</P><P>For more background and feature highlights, you can read our previous blog post and check out:</P><UL><LI><STRONG>Landing Page:</STRONG> <A href="https://spreadsheet-importer.com/" target="_blank" rel="noopener nofollow noreferrer">https://spreadsheet-importer.com/</A></LI><LI><STRONG>GitHub Repo:</STRONG> <A href="https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter" target="_blank" rel="noopener nofollow noreferrer">https://github.com/spreadsheetimporter/ui5-cc-spreadsheetimporter</A></LI></UL> 2024-12-09T10:59:37.060000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/sapui5-meets-typescript-a-smooth-migration-journey-with-joule/ba-p/13958872 SAPUI5 Meets TypeScript: A Smooth Migration Journey with Joule 2024-12-10T09:13:54.586000+01:00 martinhaeuser https://community.sap.com/t5/user/viewprofilepage/user-id/1427432 <P>As announced in March in <A href="https://community.sap.com/t5/technology-blogs-by-sap/joule-for-freestyle-sapui5-development-in-sap-build-code/ba-p/13650005" target="_blank">this blog post</A>&nbsp;by <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/4124">@OliverGraeff</a>, the UI5 team has taken its first glance into the world of generative AI as a contribution to Joule in SAP Build Code. This blog post is dedicated to providing insights into the latest feature that offers AI-driven migration of UI5 applications to TypeScript.</P><P><FONT size="5"><STRONG>TypeScript and UI5 – how can I use it ?</STRONG></FONT></P><P>Since 2023, UI5 applications can officially be implemented in TypeScript by generating projects configured for transpiling of TypeScript or by migrating the project structure as described in <A href="https://community.sap.com/t5/technology-blogs-by-sap/typescript-for-ui5-yay-it-s-official-and-a-round-up-of-recent-changes/ba-p/13570051" target="_blank">this blog post</A> by <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/189706">@AndreasKunz</a>.</P><P>In addition to converting the JavaScript code to TypeScript, migrating UI5 projects to use TypeScript requires installing the required dependencies to the project and to enhance the build and server configuration with the ‘ui5-tooling-transpile-task’ and ‘ui5-tooling-transpile-middleware’.</P><P>Joule now provides AI-driven convenience functionality to migrate existing UI5 applications according to the latest recommendations on how to enable TypeScript.</P><P><FONT size="5"><STRONG>Let’s migrate to TypeScript with Joule!</STRONG></FONT></P><P>When using Joule in SAP Business Application Studio, there is now an additional <STRONG>/ui5</STRONG> prefixed slash command <STRONG>/ui5-typescript</STRONG> for UI5 applications available.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="martinhaeuser_0-1733735297554.png" style="width: 635px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199841iE1FA3AF71201CCB2/image-dimensions/635x142?v=v2" width="635" height="142" role="button" title="martinhaeuser_0-1733735297554.png" alt="martinhaeuser_0-1733735297554.png" /></span></P><P>While the standard<STRONG> /ui5</STRONG> command can be used for general queries regarding UI5 development, <STRONG>/ui5-typescript</STRONG> will specifically provide options meant to migrate existing JavaScript-based UI5 applications to TypeScript. As soon as the command is selected, a list of suggestions will appear.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="martinhaeuser_1-1733735297555.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199842iE1EC9040CB97D8B8/image-size/large?v=v2&amp;px=999" role="button" title="martinhaeuser_1-1733735297555.png" alt="martinhaeuser_1-1733735297555.png" /></span></P><P><FONT size="5"><STRONG>Migrating the project setup</STRONG></FONT></P><P>If you&nbsp; begin to write controller code in TypeScript, you need to migrate the existing project first to enable the required tooling.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture 1.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199955i61A46A8E0A9C066E/image-size/large?v=v2&amp;px=999" role="button" title="Picture 1.png" alt="Picture 1.png" /></span></P><P> </P><P>What’s happening here? After sending the prompt, Joule will recognize the project structure of the application and adjust the dependencies in the package.json and configuration in the ui5.yaml. A click on the files displayed in the list will show the changes made by Joule and AI, here, for example, the changes made for package.json:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture 2.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/199956i57D8E8B2E4166E7A/image-size/large?v=v2&amp;px=999" role="button" title="Picture 2.png" alt="Picture 2.png" /></span></P><P>In addition to using AI, Joule will check the npm registry to retrieve the latest stable releases for the required dependencies, therefore the responses are a hybrid of AI and tooling-driven migration. The results should nevertheless always be double-checked before accepting them. For example, as shown in this screenshot, AI recommends doing a major upgrade of the UI5 CLI, which should be evaluated and tested.</P><P>The “Accept” button in the file list can be used to accept all file changes at once. This will also include necessary files, such as the newly added tsconfig.json, to configure your migrated UI5 project.</P><P><FONT size="5"><STRONG>Migrating controller files</STRONG></FONT></P><P>After successfully migrating the project, we recommend to migrate smaller batches of controllers to TypeScript. Again, select the <STRONG>/ui5-typescript</STRONG> command in Joule – the suggestions will provide the currently selected controller file in your project that will be migrated to TypeScript. The results can again be checked by clicking on the resulting files to view the differences.</P><P>As soon as the “Accept” button is pressed, the previous *.controller.js file will be deleted and replaced with the accepted *.controller.ts file.</P><P>You can also directly use <STRONG>/ui5-typescript</STRONG> and specifically ask for certain JavaScript files to be migrated. The recommendation is to migrate files in your application step by step to get the best possible results.</P><P><FONT size="5"><STRONG>Still eager to learn more about UI5 and AI? These blog posts might be interesting for you!</STRONG></FONT></P><UL><LI><A href="https://community.sap.com/t5/technology-blogs-by-sap/now-ai-helps-you-developing-sapui5-applications/ba-p/13649767" target="_self">Now AI Helps You Developing SAPUI5 Applications</A></LI><LI><A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-tools-2403-introduces-gen-ai-capability-and-more/ba-p/13650594" target="_self">SAP Fiori tools 2403 introduces Gen AI capability and more</A>&nbsp;</LI><LI><A href="https://community.sap.com/t5/technology-blogs-by-sap/ui5-freestyle-development-in-sap-build-code-with-joule/ba-p/13897852" target="_self">UI5 freestyle development in SAP Build Code with Joule</A>&nbsp;</LI></UL><P>&nbsp;</P> 2024-12-10T09:13:54.586000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/extending-sapui5-apps-adaptation-projects-vs-extension-projects/ba-p/13961264 Extending SAPUI5 apps: Adaptation projects vs. Extension projects 2024-12-12T07:39:28.256000+01:00 OliverGraeff https://community.sap.com/t5/user/viewprofilepage/user-id/4124 <H1 id="toc-hId-948375135"><STRONG>SAPUI5 flexibility to adapt standard SAP apps</STRONG></H1><P>SAPUI5 is SAP’s strategic Web framework for Web applications such as SAP Fiori. In this context, SAPUI5 flexibility offers capabilities to adapt standard apps, not only for developers but also for key users and end users using simple WYSIWYG drag and drop tools. Learn about all the capabilities:&nbsp;<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>. SAPUI5 flexibility provides features to realize a clean core approach with on-stack extensions: SAP standard apps remain untouched, no modifications are needed, and even predefined extension points are unnecessary.</P><H1 id="toc-hId-751861630"><STRONG><BR />SAPUI5 flexibility - Developer adaptation</STRONG></H1><P>Developers can leverage the concepts of SAPUI5 flexibility by using SAPUI5 adaptation projects in SAP Business Application Studio (BAS), the development environment of&nbsp;<SPAN><A href="https://www.sap.com/products/technology-platform/developer-tools.html" target="_blank" rel="noopener noreferrer">SAP Build Code</A></SPAN>. Those projects contain all code-based custom adaptations, created in the <SPAN><A href="https://community.sap.com/t5/technology-blogs-by-sap/introducing-the-new-adaptation-editor-experience-for-sapui5-adaptation/ba-p/13923903" target="_blank">new Adaptation Editor</A></SPAN> and other code editors of BAS.<FONT color="#000000"><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="AdaptationEditor.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/200762i5A1B1A8DEB15CF22/image-size/large?v=v2&amp;px=999" role="button" title="AdaptationEditor.png" alt="AdaptationEditor.png" /></span></FONT></P><P style=" text-align: center; ">Picture:&nbsp;The new Adaptation Editor in SAP Business Application Studio</P><H1 id="toc-hId-555348125"><STRONG><BR />Extension project vs. Adaptation project</STRONG></H1><P>While adaptation projects are the strategic, advanced technology for code-based extensions of SAPUI5 apps, we also have the predecessor extension projects. To address frequent confusions, I want to summarize the differences to help understanding what you see in your system:</P><TABLE border="1" width="100%"><TBODY><TR><TD width="33.333333333333336%">&nbsp;</TD><TD width="33.333333333333336%"><STRONG>Extension project</STRONG></TD><TD width="33.333333333333336%"><STRONG>Adaptation project</STRONG></TD></TR><TR><TD width="33.333333333333336%"><STRONG>SAP strategy&nbsp;&nbsp;</STRONG></TD><TD width="33.333333333333336%">Legacy usage</TD><TD width="33.333333333333336%">Strategic, advanced approach, leveraging SAPUI5 flexibility concepts</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Extend</STRONG></TD><TD width="33.333333333333336%">only legacy apps not (yet) compliant to SAPUI5 adaptation projects (1.)</TD><TD width="33.333333333333336%">most apps, as given in <A href="https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/" target="_self" rel="nofollow noopener noreferrer">SAP Fiori Apps Reference Library</A> -&gt; Implementation Information -&gt; Extensibility via SAPUI5 Adaptation Projects. (2.)</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Prerequisites</STRONG></TD><TD width="33.333333333333336%">Individual, predefined extension points in each app</TD><TD width="33.333333333333336%">General enablement of app (1.)</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Supported applications</STRONG></TD><TD width="33.333333333333336%">Freestyle SAPUI5 apps only</TD><TD width="33.333333333333336%">Any SAPUI5 app (freestyle SAPUI5 and SAP Fiori elements apps)</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Extension options</STRONG></TD><TD width="33.333333333333336%">Limited options (e.g. no extension of lifecycle methods)</TD><TD width="33.333333333333336%">Increased <A href="https://help.sap.com/docs/UI5_FLEXIBILITY/430e2c1a4ff241bc8162df4bf51e0730/a3e9d764dc8841468f73fd7cabc07cec.html?language=en-US" target="_self" rel="noopener noreferrer">options for all essential app artefacts</A></TD></TR><TR><TD width="33.333333333333336%"><STRONG>Extension location</STRONG></TD><TD width="33.333333333333336%">Extend in predefined extension points only</TD><TD width="33.333333333333336%">Extend anywhere (3.) (unless blocked by application logic)</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Stability with upgrades</STRONG></TD><TD width="33.333333333333336%">Limited stability</TD><TD width="33.333333333333336%">Improved stability</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Future-proof concept</STRONG></TD><TD width="33.333333333333336%">One layer of changes</TD><TD width="33.333333333333336%">Multiple layers possible (planned)</TD></TR><TR><TD width="33.333333333333336%"><STRONG>Platform support</STRONG></TD><TD width="33.333333333333336%">SAP S/4HANA on-prem only</TD><TD width="33.333333333333336%">Any platform (4.)</TD></TR></TBODY></TABLE><P>Footnotes</P><OL><LI>Details on prerequisites for respective platforms in <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>.</LI><LI>If an adaptation project is being created for an app not compliant to SAPUI5 adaptation projects, the wizard in SAP Business Application Studio automatically creates an extension project. (An example for such an app is My Inbox.)</LI><LI>including existing extension points, controller hooks</LI><LI>See details in <SPAN><A href="https://help.sap.com/docs/UI5_FLEXIBILITY/430e2c1a4ff241bc8162df4bf51e0730/41ada93054994698ab9067855bb85fe1.html?language=en-US" target="_blank" rel="noopener noreferrer">Features and Availability</A></SPAN>.</LI></OL><H1 id="toc-hId-358834620"><STRONG>What does this mean for existing extension projects?</STRONG></H1><P>If you have an existing extension project, you can continue using it, i.e. running it and also maintaining it. In case a) you are planning to add new extensions due to bigger requirements and b) the underlying standard app supports SAPUI5 adaptation projects (see above), SAP recommends to manually migrate the extension project to an adaptation project to make use of its advanced options. (The UI5 team currently plans to provide guidance for this manual migration.)</P><H2 id="toc-hId-291403834"><STRONG>Further references</STRONG></H2><UL><LI>Migrate from SAP Web IDE to SAP Business Application Studio: <SPAN><A href="https://blogs.sap.com/2022/01/10/its-time-to-plan-your-move-to-sap-business-application-studio/" target="_blank" rel="noopener noreferrer">Blog post </A></SPAN>&amp; <SPAN><A href="https://discovery-center.cloud.sap/missiondetail/3483/3523/" target="_blank" rel="noopener nofollow noreferrer">Mission</A></SPAN></LI><LI><SPAN><A href="https://blogs.sap.com/2022/01/26/sap-fiori-elements-adaptation-project-adding-a-custom-filter-to-the-list-report/" target="_blank" rel="noopener noreferrer">SAP Fiori Elements: Adaptation Project – Adding a Custom Filter to the List Report</A></SPAN></LI><LI><SPAN><A href="https://blogs.sap.com/2022/05/06/adaptation-project-freestyle-sapui5-app-adding-a-search-link-to-items-on-a-table/" target="_blank" rel="noopener noreferrer">Adaptation Project: Freestyle SAPUI5 App – Adding a Search Link to Items on a Table</A></SPAN></LI><LI><SPAN><A href="https://developers.sap.com/group.sapui5-adaptation-projects.html" target="_blank" rel="noopener noreferrer">Work with SAPUI5 Adaptation Projects to extend SAP S/4HANA Cloud Public Edition</A></SPAN></LI></UL> 2024-12-12T07:39:28.256000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/theme-specific-css-for-your-application/ba-p/13961249 Theme-specific CSS for your application 2024-12-12T08:35:12.488000+01:00 dsch https://community.sap.com/t5/user/viewprofilepage/user-id/162522 <P>Do you have self-developed applications built with SAPUI5, UI5 WebComponents, Fundamental NGX or even one of SAPs classic UIs? Or e.g. your own in-house SAPUI5 component library? Then, it is likely that you've felt the need for&nbsp;<STRONG>theme-specific CSS</STRONG>.</P><H2 id="toc-hId-1077457797">How it was: JavaScript and FOUC</H2><P>In the past, this was barely possible. In the SAPUI5 world, you had to resort to the <A href="https://ui5.sap.com/#/api/sap.ui.core.theming.Parameters%23methods/sap.ui.core.theming.Parameters.get" target="_blank" rel="noopener noreferrer">Parameters.get()</A> API and create your CSS in JavaScript. In general, you had to inspect the applied theme at runtime, using JavaScript, and serve your theme-specific CSS based on the inspection result. This leads to flashes-of-unstyled-content (FOUC), which, again, has to be treated.</P><H2 id="toc-hId-880944292">What we have now: sapSapThemeId</H2><P>But not anymore! [1]</P><P>With <A href="https://github.com/SAP/theming-base-content/releases/tag/11.23.0" target="_blank" rel="noopener nofollow noreferrer">theming base content 11.23.0</A>, we introduced the new theming parameter <FONT face="courier new,courier">sapSapThemeId</FONT>. This parameter always contains the technical id of the SAP-provided theme the applied theme is based on (in case of a custom-theme) or of the applied theme itself. I.e. <FONT face="courier new,courier">--sapSapThemeId</FONT> of sap_horizon is <FONT face="courier new,courier">sap_horizon</FONT>, and <FONT face="courier new,courier">sapSapThemeId</FONT> of my_horizon (a custom theme based on sap_horizon) is also <FONT face="courier new,courier">sap_horizon</FONT>.</P><H2 id="toc-hId-684430787">Disclaimer: use existing parameters</H2><P>The technique I'm about to describe, is a "last resort" solution. Always check first</P><OL><LI>if there is already a theming parameter you could use instead – Use the <A href="https://sap.github.io/theming-base-content/docs/#/parameters" target="_blank" rel="noopener nofollow noreferrer">parameter explorer</A> of the theming base content to get an overview of what's already there;</LI><LI>if it would make sense to add a theming parameter to the theming base content – Write a comment here, <A href="https://github.com/SAP/theming-base-content/issues/new" target="_self" rel="nofollow noopener noreferrer">create an issue</A> for the theming base content or contact the development team directly.</LI></OL><P>Only if both checks are answered negatively, you should use <FONT face="courier new,courier">sapSapThemeId</FONT> to bring your own "delta" css.</P><H2 id="toc-hId-487917282">The idea: container style queries</H2><P>The idea is to craft a <A href="https://developer.mozilla.org/en-US/docs/Web/CSS/@container#container_style_queries" target="_self" rel="nofollow noopener noreferrer">container style query</A> against <FONT face="courier new,courier">--sapSapThemeId</FONT>&nbsp;(the CSS custom property version of <FONT face="courier new,courier">sapSapThemeId</FONT>), and define your own custom properties based on the result. In the example, I'll use <A href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors#using_custom_properties" target="_self" rel="nofollow noopener noreferrer">relative colors</A> to darken a background in light themes and lighten it in dark themes; and I'll use <A href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting" target="_self" rel="nofollow noopener noreferrer">CSS nesting</A> for a more concise example; but both are not strictly necessary.</P><H3 id="toc-hId-420486496">Example: a custom list item</H3><P>As an example, imagine the background color of a custom list item (which is identified by the CSS class&nbsp;<FONT face="courier new,courier">myListItem</FONT>). It should depend on <A href="https://sap.github.io/theming-base-content/docs/#/parameters?search=sapList_Background" target="_self" rel="nofollow noopener noreferrer"><FONT face="courier new,courier">sapList_Background</FONT></A>, but be 10% darker than that in light themes, 10% lighter than that in dark themes, with 30% instead of 10% for high-contrast themes.</P><P>For that, we'll create our own CSS custom property, <FONT face="courier new,courier">--myList_Background</FONT>, that defaults to <FONT face="courier new,courier">--sapList_Background</FONT>:</P><P>&nbsp;</P><pre class="lia-code-sample language-css"><code>:root { --myList_Background: var(--sapList_Background); }</code></pre><P>&nbsp;</P><P>Next, we'll use that custom property in the <FONT face="courier new,courier">.myListItem</FONT> selector:</P><P>&nbsp;</P><pre class="lia-code-sample language-css"><code>.myListItem { background-color: var(--myList_Background); }</code></pre><P>&nbsp;</P><P>And now, we'll overwrite the value of <FONT face="courier new,courier">--myList_Background</FONT> in the <FONT face="courier new,courier">body</FONT> selector based on the container style query value of <FONT face="courier new,courier">--sapSapThemeId</FONT>:</P><P>&nbsp;</P><pre class="lia-code-sample language-css"><code>body { /* light low-contrast themes */ @container style(--sapSapThemeId: sap_horizon) or style(--sapSapThemeId: sap_fiori_3) { /* darken by 10% */ --myList_Background: hsl(from var(--sapList_Background) h s calc(l - 10)); } /* dark low-contrast themes */ @container style(--sapSapThemeId: sap_horizon_dark) or style(--sapSapThemeId: sap_fiori_3_dark) { /* lighten by 10% */ --myList_Background: hsl(from var(--sapList_Background) h s calc(l + 10)); } /* light high-contrast themes */ @container style(--sapSapThemeId: sap_horizon_hcw) or style(--sapSapThemeId: sap_fiori_3_hcw) { /* darken by 30% */ --myList_Background: hsl(from var(--sapList_Background) h s calc(l - 30)); } /* dark high-contrast themes */ @container style(--sapSapThemeId: sap_horizon_hcb) or style(--sapSapThemeId: sap_fiori_3_hcb) { /* lighten by 30% */ --myList_Background: hsl(from var(--sapList_Background) h s calc(l + 30)); } }</code></pre><P>&nbsp;</P><P>That's it, now our custom list item has a custom background that is still connected to the official theming variables, and that depends on the actually applied theme.</P><H2 id="toc-hId-94890272">A bit of background: container style queries</H2><P>So, why does that work?</P><P>MDN does a good job explaining <A href="https://developer.mozilla.org/en-US/docs/Web/CSS/@container#container_style_queries" target="_self" rel="nofollow noopener noreferrer">container style queries</A>, so this is just a small gist.</P><P>The <FONT face="courier new,courier">--sapSapThemeId</FONT> custom property is, like all custom properties of the theming base content, defined at <FONT face="courier new,courier">:root</FONT>, which usually is the <FONT face="courier new,courier">&lt;html&gt;</FONT> element. It is crucial that this also is a containment context (the outermost containment context even).</P><P>The <FONT face="courier new,courier">&lt;body&gt;</FONT> is inside <FONT face="courier new,courier">:root</FONT> (the <FONT face="courier new,courier">&lt;html&gt;</FONT>), so container styles applied to the <FONT face="courier new,courier">&lt;html&gt;</FONT> containment context have an effect on the <FONT face="courier new,courier">&lt;body&gt;</FONT>.</P><P>The CSS</P><P>&nbsp;</P><pre class="lia-code-sample language-css"><code>body { @container style(--sapSapThemeId: sap_horizon) { --myList_Background: #c0ffee; } } /* which is a more concise version of */ @container style(--sapSapThemeId: sap_horizon) { body { --myList_Background: #c0ffee; } }</code></pre><P>&nbsp;</P><P>could be read as</P><UL><LI>In any container (<FONT face="courier new,courier"><a href="https://community.sap.com/t5/user/viewprofilepage/user-id/823820">@container</a></FONT> without a <FONT face="courier new,courier">&lt;container-name&gt;</FONT>),</LI><LI>on which the custom property <FONT face="courier new,courier">--sapSapThemeId</FONT> has the value <FONT face="courier new,courier">sap_horizon</FONT>,</LI><LI>in <FONT face="courier new,courier">body</FONT> elements (which is only the one <FONT face="courier new,courier">&lt;body&gt;</FONT> that contains all visible parts of an html page)</LI><LI>the custom property <FONT face="courier new,courier">--myList_Background</FONT></LI><LI>has the value <FONT face="courier new,courier">#c0ffee</FONT></LI></UL><P>In the example, we also used <A href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors" target="_self" rel="nofollow noopener noreferrer">relative colors</A>, which could be the topic of a separate blog post.</P><H2 id="toc-hId--101623233">Recap:&nbsp;theme-specific CSS without JavaScript</H2><P>We have seen that since theming base content 11.23.0, which will soon be available in SAPUI5 (likely version 1.132, but I can't promise anything) and classic UIs (UR/c2 2413), you can write a container style query against <FONT face="courier new,courier">--sapSapThemeId</FONT> to change values of your own CSS custom properties, or even add theme-specific selectors.</P><P>Please try that out and leave a comment how it went.</P><HR /><H2 id="toc-hId--298136738">Footnotes</H2><P>[1] The described technique relies on <I>container style queries for custom properties</I>, actively implemented but not yet supported in Firefox (see tracking bug <A href="https://bugzil.la/1795622" target="_blank" rel="noopener nofollow noreferrer">1795622</A>)</P> 2024-12-12T08:35:12.488000+01:00 https://community.sap.com/t5/technology-blogs-by-members/nfc-scanning-in-work-zone/ba-p/13963468 NFC scanning in Work Zone 2024-12-17T07:41:35.705000+01:00 WouterLemaire https://community.sap.com/t5/user/viewprofilepage/user-id/9863 <H1 id="toc-hId-948436643"><SPAN>Introduction</SPAN></H1><P><SPAN>With the evolution of browsers on mobile devices more native functionalities are possible in browser based application on a mobile device, a good example of this it NFC scanning. In the past this required you to make a Hybrid or Native mobile app. Nowadays, this is perfectly possible on any Android device that has NFC scanning from in the browser using the web NFC api: <A href="https://developer.mozilla.org/en-US/docs/Web/API/Web_NFC_API" target="_blank" rel="nofollow noopener noreferrer">Web NFC API - Web APIs | MDN (mozilla.org)</A></SPAN></P><P><SPAN>For iOS, this is still not possible because security constrains in iOS. In case of Fiori, you’ll have to create an MDK application with a plugin for NFC scanning as explained here: &nbsp;<A href="https://community.sap.com/t5/technology-blogs-by-members/mdk-ios-nfc-uid-scanner-how-to-use-native-functionalities-in-sap-mdk-using/ba-p/13553764" target="_blank">https://community.sap.com/t5/technology-blogs-by-members/mdk-ios-nfc-uid-scanner-how-to-use-native-functionalities-in-sap-mdk-using/ba-p/13553764</A> </SPAN></P><P><SPAN>This could help you for your new Fiori projects to have NFC scanning functionality. It can also help you to move away from Hybrid or Native Mobile applications which you might have running on BTP Mobile Services. This will save costs of Mobile Service, Mobile Device Management and simplify your application.</SPAN></P><H1 id="toc-hId-751923138"><SPAN>Problem</SPAN></H1><P><SPAN>Using this in a UI5/Fiori application is super easy to do using the browser API for this. Unfortunately, when you want to integrate this application in BTP Work Zone, it won’t work anymore. Work Zone uses iframes for opening applications and the NFC API&nbsp; can only be used on the top level frames for security reasons.</SPAN></P><P><SPAN>See the documentation:</SPAN></P><P><SPAN>Scan: <A href="https://developer.mozilla.org/en-US/docs/Web/API/NDEFReader/scan" target="_blank" rel="nofollow noopener noreferrer">NDEFReader: scan() method - Web APIs | MDN (mozilla.org)</A></SPAN></P><P><SPAN>“</SPAN>Web NFC is only available to top-level frames and secure browsing contexts (HTTPS only).&nbsp;<SPAN>”</SPAN></P><P><SPAN><A href="https://developer.chrome.com/docs/capabilities/nfc#security-and-permissions" target="_blank" rel="nofollow noopener noreferrer">Interact with NFC devices on Chrome for Android &nbsp;|&nbsp; Capabilities &nbsp;|&nbsp; Chrome for Developers</A></SPAN></P><H1 id="toc-hId-555409633">Solution</H1><P>As a workaround, I came up with a plugin for Work Zone to make this possible. This plugin will be loaded on the top level frame of Work Zone and trigger the scanning. To notify the application running in Work Zone, I use IFrame communication.</P><P>The plugin contains only a “Component.ts” file:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="WouterLemaire_0-1734130383475.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/201664i420ED3915F41FB04/image-size/medium?v=v2&amp;px=400" role="button" title="WouterLemaire_0-1734130383475.png" alt="WouterLemaire_0-1734130383475.png" /></span></P><P>&nbsp;</P><P>In the Component.ts file, &nbsp;I create the NDEFReader object, provide a success handler to get the scanned object and error handler to know in case something goes wrong. In the end, this will activate the NFC scanner of the device and capture any NFC scanned during your session:</P><pre class="lia-code-sample language-javascript"><code>const ndef = new NDEFReader(); ndef.onreading = (event) =&gt; { console.log("Message:"); console.log(JSON.stringify(event.message)); const data = event.message.records[0].data; let decoder = new TextDecoder("utf-8"); let scan = decoder.decode(data); }; ndef.onreadingerror = (event) =&gt; { }; await ndef.scan();</code></pre><P>Now, to inform the application that triggered the NFC scan with the result, I add the following code to the onRead event handler:</P><UL><LI>It gets all the iframe’s in Work Zone</LI><LI>Loops over them</LI><LI>Posts the result to all the iframes</LI></UL><pre class="lia-code-sample language-javascript"><code>const iframes = document.querySelectorAll('iframe'); for (const iframe of iframes) { iframe.contentWindow?.postMessage({ action: "NFCSCANNED", tag: {id:scan} }, "*"); }</code></pre><P>Same for the Error event handler but using another action:</P><pre class="lia-code-sample language-javascript"><code>const iframes = document.querySelectorAll('iframe'); for (const iframe of iframes) { iframe.contentWindow?.postMessage({ action: "NFCSCANNED", tag: {id:scan} }, "*"); }</code></pre><P>Full code of the Component.ts file:</P><pre class="lia-code-sample language-javascript"><code>import MessageBox from "sap/m/MessageBox"; import BaseComponent from "sap/ui/core/UIComponent"; /** * @namespace be.nmbs.plugins.nfcscanning */ export default class Component extends BaseComponent { public static metadata = { manifest: "json" }; /** * The component is initialized by UI5 automatically during the startup of the app and calls the init method once. * <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1820957">@Public</a> * @override */ public async init() { // call the base component's init function super.init(); if ('NDEFReader' in window) { const ndef = new NDEFReader(); ndef.onreading = (event) =&gt; { console.log("Message:"); console.log(JSON.stringify(event.message)); const data = event.message.records[0].data; let decoder = new TextDecoder("utf-8"); let scan = decoder.decode(data); const iframes = document.querySelectorAll('iframe'); for (const iframe of iframes) { iframe.contentWindow?.postMessage({ action: "NFCSCANNED", tag: {id:scan} }, "*"); } }; ndef.onreadingerror = (event) =&gt; { const iframes = document.querySelectorAll('iframe'); for (const iframe of iframes) { iframe.contentWindow?.postMessage({ action: "NFCSCANNED-ERROR", tag: {id:""} }, "*"); } }; await ndef.scan(); } } }</code></pre><P>To consume this in an application, I do the following in the eventhandler of a button:</P><UL><LI>Register an eventhandler to catch the result</LI><LI>Trigger the message to the parent to inform that we want to start a scan</LI></UL><P>Consuming could look like this:</P><pre class="lia-code-sample language-javascript"><code>onclick: async function (oEvent) { window.addEventListener('message', (event)=&gt;this.readTag(event)); }, readTag: function (event) { if(!event.data || !event.data.action || event.data.action !== "NFCSCANNED"){ return; } MessageToast.show(`NFC Scan result: ${event.data.tag}`); } }</code></pre><P>For using typescript, it might be useful to have the NFC typescript definition file: Web-nfc.d.ts</P><pre class="lia-code-sample language-javascript"><code>// Type definitions for Web NFC // Project: https://github.com/w3c/web-nfc // Definitions by: Takefumi Yoshii &lt;https://github.com/takefumi-yoshii&gt; // TypeScript Version: 3.9 // This type definitions referenced to WebIDL. // https://w3c.github.io/web-nfc/#actual-idl-index interface Window { NDEFMessage: NDEFMessage } declare class NDEFMessage { constructor(messageInit: NDEFMessageInit) records: ReadonlyArray&lt;NDEFRecord&gt; } declare interface NDEFMessageInit { records: NDEFRecordInit[] } declare type NDEFRecordDataSource = string | BufferSource | NDEFMessageInit interface Window { NDEFRecord: NDEFRecord } declare class NDEFRecord { constructor(recordInit: NDEFRecordInit) readonly recordType: string readonly mediaType?: string readonly id?: string readonly data?: DataView readonly encoding?: string readonly lang?: string toRecords?: () =&gt; NDEFRecord[] } declare interface NDEFRecordInit { recordType: string mediaType?: string id?: string encoding?: string lang?: string data?: NDEFRecordDataSource } declare type NDEFMessageSource = string | BufferSource | NDEFMessageInit interface Window { NDEFReader: NDEFReader } declare class NDEFReader extends EventTarget { constructor() onreading: (this: this, event: NDEFReadingEvent) =&gt; any onreadingerror: (this: this, error: Event) =&gt; any scan: (options?: NDEFScanOptions) =&gt; Promise&lt;void&gt; write: ( message: NDEFMessageSource, options?: NDEFWriteOptions ) =&gt; Promise&lt;void&gt; makeReadOnly: (options?: NDEFMakeReadOnlyOptions) =&gt; Promise&lt;void&gt; } interface Window { NDEFReadingEvent: NDEFReadingEvent } declare class NDEFReadingEvent extends Event { constructor(type: string, readingEventInitDict: NDEFReadingEventInit) serialNumber: string message: NDEFMessage } interface NDEFReadingEventInit extends EventInit { serialNumber?: string message: NDEFMessageInit } interface NDEFWriteOptions { overwrite?: boolean signal?: AbortSignal } interface NDEFMakeReadOnlyOptions { signal?: AbortSignal } interface NDEFScanOptions { signal: AbortSignal }</code></pre> 2024-12-17T07:41:35.705000+01:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-members/sapui5-custom-application-digital-signature-draw-pad/ba-p/13967618 SAPUI5 Custom Application: Digital Signature Draw Pad 2024-12-18T20:11:32.809000+01:00 Mahmoud-Farag https://community.sap.com/t5/user/viewprofilepage/user-id/45055 <H2 id="toc-hId-1077640293"><SPAN>Business Case</SPAN></H2><P><SPAN>This blog showcases a custom SAP UI5 application that allows users to draw a signature on a digital pad, clear it, download it as an image (JPEG), or upload it to an SAP backend server for further processing. The application is built using the <EM>HTML5</EM> control within the SAP UI5 framework.<BR /></SPAN><SPAN>It is designed to handle both desktop and touch devices such as mobile phones and tablets, ensuring broad usability across platforms.</SPAN></P><H2 id="toc-hId-881126788"><SPAN><BR />Features</SPAN></H2><UL><LI><P><SPAN><STRONG>Draw Signature:</STRONG></SPAN><SPAN> Users can draw their signatures on a responsive digital canvas.</SPAN></P></LI><LI><P><SPAN><STRONG>Clear Pad:</STRONG></SPAN><SPAN> The pad can be reset with a single click.</SPAN></P></LI><LI><P><SPAN><STRONG>Download Signature:</STRONG></SPAN><SPAN> Users can save their signature locally as a JPEG file.</SPAN></P></LI><LI><P><SPAN><STRONG>Upload to Server:</STRONG></SPAN><SPAN> The application provides functionality to save the signature to an SAP server for storage or further processing.</SPAN></P></LI><LI><P><SPAN><STRONG>Touch Device Support:</STRONG></SPAN><SPAN> Fully functional on mobile devices and tablets with touch input support.</SPAN></P></LI></UL><H2 id="toc-hId-684613283"><SPAN>Application Structure</SPAN></H2><P><SPAN>The application is implemented with a combination of SAP UI5 and HTML5 canvas features. Below is a breakdown of the technical components.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="MahmoudFarag_0-1734547492116.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203423iE8FC3AEA4D1CD6CF/image-size/medium?v=v2&amp;px=400" role="button" title="MahmoudFarag_0-1734547492116.png" alt="MahmoudFarag_0-1734547492116.png" /></span></P><H3 id="toc-hId-617182497"><SPAN>XML View</SPAN></H3><P><SPAN>The XML view defines the structure and layout of the application, incorporating an HTML control for the canvas and buttons for actions:</SPAN></P><P>&nbsp;</P><pre class="lia-code-sample language-markup"><code>&lt;mvc:View controllerName="digitalsignature.controller.View1" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" xmlns="sap.m"&gt; &lt;Page id="_IDGenPage" title="Digital Signature"&gt; &lt;content&gt; &lt;VBox id="_IDGenVBox1" class="sapUiSmallMargin"&gt; &lt;HBox id="_IDGenHBox"&gt; &lt;Text id="_IDGenText" text="Draw your signature below:" /&gt; &lt;/HBox&gt; &lt;HBox id="_IDGenHBox1"&gt; &lt;core:HTML id="signaturePad" content="{/signatureHTML}" afterRendering=".onAfterRenderingHTML" /&gt; &lt;HBox alignItems="End" id="_IDGenHBox2" justifyContent="SpaceBetween" class="sapUiSmallMarginTop"&gt; &lt;Button id="_IDGenButton1" text="Clear" press=".onClearPress" /&gt; &lt;Button id="_IDGenButton2" text="Download as JPEG" press=".onDownloadPress" /&gt; &lt;Button id="_IDGenButton3" text="Upload to Server" press=".onPostToServer" /&gt; &lt;/HBox&gt; &lt;/HBox&gt; &lt;/VBox&gt; &lt;/content&gt; &lt;/Page&gt; &lt;/mvc:View&gt;</code></pre><P>&nbsp;</P><H3 id="toc-hId-420668992"><SPAN>Controller Logic</SPAN></H3><P><SPAN>The controller implements the core functionality of the application. It handles user interactions, such as drawing on the canvas, clearing it, and downloading the signature as an image.</SPAN></P><H4 id="toc-hId-353238206"><SPAN>Initialization and Canvas Rendering</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>onInit: function () { const signatureHTML = "&lt;canvas id='signatureCanvas' width='500' height='300' style='border:1px solid #000;'&gt;&lt;/canvas&gt;"; const oModel = new sap.ui.model.json.JSONModel({ signatureHTML: signatureHTML }); this.getView().setModel(oModel); this._canvas = null; this._ctx = null; this._isDrawing = false; }, onAfterRenderingHTML: function () { this._canvas = document.getElementById("signatureCanvas"); if (this._canvas) { this._ctx = this._canvas.getContext("2d"); this._setCanvasBackground(); this._attachMouseEvents(); this._attachTouchEvents(); } else { console.error("Canvas element not found. Check your HTML content and IDs."); } },</code></pre><P>&nbsp;</P><H4 id="toc-hId-156724701"><SPAN>Drawing and Clearing Signature</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>_startDrawing: function (event) { this._isDrawing = true; this._ctx.beginPath(); this._ctx.moveTo(event.offsetX, event.offsetY); }, _draw: function (event) { if (!this._isDrawing) return; this._ctx.lineTo(event.offsetX, event.offsetY); this._ctx.strokeStyle = "#000"; this._ctx.lineWidth = 2; this._ctx.stroke(); }, onClearPress: function () { if (this._canvas) { this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); this._setCanvasBackground(); MessageToast.show("Signature pad cleared."); } },</code></pre><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="MahmoudFarag_1-1734547527223.png" style="width: 560px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203425i8451355BBE7EA81A/image-dimensions/560x254?v=v2" width="560" height="254" role="button" title="MahmoudFarag_1-1734547527223.png" alt="MahmoudFarag_1-1734547527223.png" /></span></P><H4 id="toc-hId--39788804"><SPAN>Full Controller Code:</SPAN></H4><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/model/json/JSONModel", ], function (Controller, MessageToast, JSONModel) { "use strict"; return Controller.extend("digitalsignature.controller.View1", { onInit: function () { const signatureHTML = "&lt;canvas id='signatureCanvas' width='500' height='300' style='border:1px solid #000;'&gt;&lt;/canvas&gt;"; const oModel = new sap.ui.model.json.JSONModel({ signatureHTML: signatureHTML }); this.getView().setModel(oModel); this._canvas = null; this._ctx = null; this._isDrawing = false; }, onAfterRenderingHTML: function () { this._canvas = document.getElementById("signatureCanvas"); if (this._canvas) { this._ctx = this._canvas.getContext("2d"); this._setCanvasBackground(); this._attachMouseEvents(); this._attachTouchEvents(); } else { console.error("Canvas element not found. Check your HTML content and IDs."); } }, _setCanvasBackground: function () { this._ctx.fillStyle = "#FFFFFF"; // White background this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); }, _attachMouseEvents: function () { this._canvas.addEventListener("mousedown", this._startDrawing.bind(this)); this._canvas.addEventListener("mousemove", this._draw.bind(this)); this._canvas.addEventListener("mouseup", this._stopDrawing.bind(this)); this._canvas.addEventListener("mouseleave", this._stopDrawing.bind(this)); }, _attachTouchEvents: function () { this._canvas.addEventListener("touchstart", this._startTouchDrawing.bind(this)); this._canvas.addEventListener("touchmove", this._drawTouch.bind(this)); this._canvas.addEventListener("touchend", this._stopDrawing.bind(this)); }, _startDrawing: function (event) { this._isDrawing = true; this._ctx.beginPath(); this._ctx.moveTo(event.offsetX, event.offsetY); }, _draw: function (event) { if (!this._isDrawing) return; this._ctx.lineTo(event.offsetX, event.offsetY); this._ctx.strokeStyle = "#000"; this._ctx.lineWidth = 2; this._ctx.stroke(); }, _startTouchDrawing: function (event) { event.preventDefault(); // Prevent scrolling this._isDrawing = true; const touch = event.touches[0]; const rect = this._canvas.getBoundingClientRect(); const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; this._ctx.beginPath(); this._ctx.moveTo(x, y); }, _drawTouch: function (event) { if (!this._isDrawing) return; event.preventDefault(); // Prevent scrolling const touch = event.touches[0]; const rect = this._canvas.getBoundingClientRect(); const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; this._ctx.lineTo(x, y); this._ctx.strokeStyle = "#000"; this._ctx.lineWidth = 2; this._ctx.stroke(); }, _stopDrawing: function () { this._isDrawing = false; this._ctx.closePath(); }, onClearPress: function () { if (this._canvas) { this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); this._setCanvasBackground(); MessageToast.show("Signature pad cleared."); } }, onDownloadPress: function () { if (this._canvas) { const link = document.createElement("a"); link.href = this._canvas.toDataURL("image/jpeg"); link.download = "signature.jpeg"; link.click(); MessageToast.show("Signature downloaded as JPEG."); } }, onPostToServer: function () { if (this._canvas) { const imageData = this._canvas.toDataURL("image/jpeg"); // Add server upload logic here MessageToast.show("Signature uploaded to server (mockup)."); } } }); });</code></pre><P>&nbsp;</P><H3 id="toc-hId--365385028"><SPAN>Upload to SAP Server</SPAN></H3><P><SPAN>While the implementation of server upload is included as a mockup, it can be achieved using the </SPAN><SPAN>sap.ui.model.odata</SPAN><SPAN> or </SPAN><SPAN>fetch</SPAN><SPAN> API. The signature can be sent as a base64 string to an SAP OData service.</SPAN></P><H2 id="toc-hId--690981252"><SPAN>Conclusion</SPAN></H2><P><SPAN>This SAP UI5 custom application serves as a practical example of how HTML5 capabilities can be integrated within the SAP UI5 framework to meet real-world business requirements. The Digital Signature Draw Pad enhances user experience, supports digital transformation, and simplifies workflows.&nbsp;</SPAN></P><P><SPAN>Feel free to implement this application in your SAP projects and customize it as per your needs.<BR />Happy coding!<span class="lia-unicode-emoji" title=":winking_face:">😉</span><BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="MahmoudFarag_2-1734548551178.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203436i20862F80B698A9DD/image-size/medium?v=v2&amp;px=400" role="button" title="MahmoudFarag_2-1734548551178.png" alt="MahmoudFarag_2-1734548551178.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;</SPAN></P> 2024-12-18T20:11:32.809000+01:00 https://community.sap.com/t5/application-development-blog-posts/sap-developer-news-december-19th-2024/ba-p/13968700 SAP Developer News, December 19th, 2024 2024-12-19T21:10:00.040000+01:00 thomas_jung https://community.sap.com/t5/user/viewprofilepage/user-id/139 <P><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F64gFjbU9lN0%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D64gFjbU9lN0&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F64gFjbU9lN0%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="400" height="225" scrolling="no" title="SAP Developer News" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><STRONG>Podcast:</STRONG> <A href="https://podcast.opensap.info/sap-developers/2024/12/19/sap-developer-news-december-19th-2024/" target="_blank" rel="nofollow noopener noreferrer">https://podcast.opensap.info/sap-developers/2024/12/19/sap-developer-news-december-19th-2024/</A></P><H3 id="toc-hId-1206753725">DESCRIPTION</H3><P><STRONG>SAP Developer News End of Year Schedule</STRONG></P><P><STRONG>New in SAP SDKs for AI</STRONG></P><UL><LI>SAP Cloud SDK for AI (JavaScript): <A href="https://github.com/SAP/ai-sdk-js/releases/" target="_blank" rel="nofollow noopener noreferrer">https://github.com/SAP/ai-sdk-js/releases/</A></LI><LI>SAP Cloud SDK for AI (Java): <A href="https://github.com/SAP/ai-sdk-java/releases" target="_blank" rel="nofollow noopener noreferrer">https://github.com/SAP/ai-sdk-java/releases</A></LI><LI>Generative AI Hub SDK (Python): <A href="https://help.sap.com/doc/generative-ai-hub-sdk/CLOUD" target="_blank" rel="noopener noreferrer">https://help.sap.com/doc/generative-ai-hub-sdk/CLOUD</A></LI><LI>Understand the World of AI with SAP Learning: <A href="https://community.sap.com/t5/artificial-intelligence-and-machine-learning-blogs/understand-the-world-of-ai-with-sap-learning/ba-p/13968267" target="_blank">https://community.sap.com/t5/artificial-intelligence-and-machine-learning-blogs/understand-the-world-of-ai-with-sap-learning/ba-p/13968267</A></LI></UL><P><STRONG>New series: The Art and Science of CAP with Daniel Hutzel</STRONG></P><UL><LI>Episodes and show notes <A href="https://qmacro.org/blog/posts/2024/12/06/the-art-and-science-of-cap/" target="_blank" rel="nofollow noopener noreferrer">https://qmacro.org/blog/posts/2024/12/06/the-art-and-science-of-cap/</A></LI><LI>Live stream series playlist <A href="https://www.youtube.com/playlist?list=PL6RpkC85SLQAe45xlhIfhTYB9G0mdRVjI" target="_blank" rel="nofollow noopener noreferrer">https://www.youtube.com/playlist?list=PL6RpkC85SLQAe45xlhIfhTYB9G0mdRVjI</A></LI></UL><P><STRONG>Extending SAPUI5 Apps</STRONG></P><UL><LI>Blog post: <A href="https://community.sap.com/t5/technology-blogs-by-sap/extending-sapui5-apps-adaptation-projects-vs-extension-projects/ba-p/13961264" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/extending-sapui5-apps-adaptation-projects-vs-extension-projects/ba-p/13961264</A></LI></UL><P><STRONG>SAP Data &amp; Analytics Advisory Methodology</STRONG></P><UL><LI>SAP Data &amp; Analytics Advisory Methodology Overview | SAP Help Portal: <A href="https://help.sap.com/docs/sap-btp-guidance-framework/sap-data-methodology/sap-data-analytics-advisory-methodology-overview" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/sap-btp-guidance-framework/sap-data-methodology/sap-data-analytics-advisory-methodology-overview</A></LI><LI>Highlights of SAP Datasphere in 2024: <A href="https://www.linkedin.com/posts/activity-7275068742051450881-iHTy" target="_blank" rel="nofollow noopener noreferrer">https://www.linkedin.com/posts/activity-7275068742051450881-iHTy</A></LI><LI>Watch out for our Q4 release for SAP HANA Cloud: <A href="https://www.linkedin.com/posts/thomashammersap_saphanacloud-sapbtp-saphana-activity-7272528046564282368-t2GE" target="_blank" rel="nofollow noopener noreferrer">https://www.linkedin.com/posts/thomashammersap_saphanacloud-sapbtp-saphana-activity-7272528046564282368-t2GE</A></LI></UL><H3 id="toc-hId-1010240220">CHAPTER TITLES</H3><P>0:00 Intro<BR />0:10 Dev News Schedule<BR />1:01 New in SAP SDKs for AI<BR />2:27 New series: The Art and Science of CAP with Daniel Hutzel<BR />3:52 Extending SAPUI5 Apps<BR />4:49 SAP Data &amp; Analytics Advisory Methodology</P><H3 id="toc-hId-813726715">Transcription</H3><P><STRONG>[Intro]</STRONG> This is the SAP Developer News for December 19th, 2024.</P><P><STRONG>[Tom]</STRONG> I just want to let everybody know about the upcoming plans for the developer news as we take our annual end of year break. This is the last regular news episode that we'll have for 2024. And like the previous years, we have special year and review episodes coming up for the last week of December and the first week of December. January. So you hear from each of the team members about what they reflect upon 2024, their major accomplishments, things that they've enjoyed, all those sort of things. And be on the lookout for our special bloopers. We'll throw some fun, exciting bloopers in at the end of each of those episodes and probably release that separately as well. So we look forward to seeing you back here for new episodes the second week of January 2025.</P><P><STRONG>[Witalij]</STRONG> SAP Cloud SDK for AI is our official software development kit for SAP AI core, SAP Generative AI hub and orchestration service. The JavaScript TypeScript version was introduced two months ago, and last week we released version 1.4. This new version odds support for the orchestration services grounding capabilities. Grounding allows you to integrate external, contextually, relevant, domain-specific or real-time data into your AI processes. This data supplements the natural language processing capabilities of pre-trained models, which are typically trained only on general data sets. Additionally, the Java version of the SDK has reached a significant milestone with the release of version 1.0, bringing numerous new features and enhancements. You can find the complete documentation and sample projects in the Git repository. For Python users, the Generative AI Hub SDK has recently released version 4.1.1, which is a new introduces support for prompt registry templates in orchestration. I hear feeling overwhelmed by all these terminology. No worries. If you are new to AI are wondering how SAP is embedding AI into our portfolio, check out the &nbsp;recent post by my teammate Nora. She guides you through relevant courses and activities available on SAP learning. Links are provided in the description.</P><P><STRONG>[DJ]</STRONG> If you've ever wanted to gain a deeper of CAP. Learn more about its design and the fundamental core computing building blocks upon which it's based. Then we've got a series for you. On the Hands on SAP Dev show, which we've been running since early 2019, we've got a new mini -series with none other than the creator of CAP himself, Daniel Hutzel. The series is called the Art and Science of CAP. and in each episode, Daniel takes us on journeys deep and wide, bringing enlightenment and wonder in equal measure. Now, the series was kicked off during Devtoberfest 2024. It's still running. There's an episode or two to go. And alongside the episodes, the live stream episodes, there are also show notes that you can dive into afterwards. Or you can just watch the replays of the live stream episodes. and dive into the show notes as well. There's a ton of stuff to explore and learn about. So, this holiday season, treat yourself to some amazing insights and check out the episodes that we have on offer along with your company notes. And we'll see you online.</P><P><STRONG>[Michelle]</STRONG> Hey y'all. If you're a developer working with SAPUI5, you want to check out this blog post about extension projects versus adaption projects. It's all about how SAP is moving towards a more advanced way of customizing apps with adapt projects. The post explains how Adaption Projects created an SAP Business Application Studio lets you adapt apps without modifying the standard code. You get powerful new features, improved upgrade stability, and the flexibility to work with on any SAP app, not just legacy ones. It also compares the older extension projects to adaption projects showing why adaption projects are the way forward and to give you a better idea of the differences between the two. If you're working with existing extension projects, don't worry, you can still use them, but SAP recommends migrating to an adaption project for bigger or new requirements. To learn more about the blog post, it's linked below and as always, happy coding.</P><P><STRONG>[Witalij]</STRONG> Just in time for the year end, we are happy to share that the SAP Data and Analytics advisory methodology is now officially available as part of the SAP Help Documentation. The methodology provides a comprehensive framework for enterprise and data architects to evaluate data strategies, develop solution architectures and foster a data-driven culture through a structured four-phase approach. This process is supported by a data domain reference model to establish a common understanding of SAP data, a data and analytics capability model to enhance the architectural definition process, and data-driven use-case patterns and reference architecture. to accelerate solution architecture development. Use the holiday season as an opportunity to get inspired and set the groundwork for successful data and analytics projects in the coming year. And while beyond the topic, I'd like to highlight two product-specific resources from the respective managers. The SAP DataSphere 2024 highlights presented by KP Sauer and the teaser for the Q4 release of SAP HANA cloud shared by Thomas Hammer. The links are in the description, as always.</P> 2024-12-19T21:10:00.040000+01:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-members/sapui5-custom-app-shipment-tracking-with-sapui5-and-google-maps-integration/ba-p/13970789 SAPUI5 Custom App: Shipment Tracking with SAPUI5 and Google Maps Integration 2024-12-23T22:35:09.074000+01:00 Mahmoud-Farag https://community.sap.com/t5/user/viewprofilepage/user-id/45055 <H3 id="toc-hId-1207439175"><STRONG>Business Case:</STRONG></H3><P>In the logistics industry, real-time shipment tracking is a necessity. Traditional systems often lack a visual component, leaving businesses without critical insights into routes, distances, and potential delays. <STRONG>Shipment Tracking Application</STRONG>, built with SAPUI5 and Google Maps, addresses these challenges by combining route visualization, detailed instructions, and multilingual support into a single application.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="MahmoudFarag_0-1734988678533.png" style="width: 542px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204799i88F208FC5E651E4E/image-dimensions/542x260?v=v2" width="542" height="260" role="button" title="MahmoudFarag_0-1734988678533.png" alt="MahmoudFarag_0-1734988678533.png" /></span></P><H3 id="toc-hId-1010925670"><STRONG>Features:</STRONG></H3><H4 id="toc-hId-943494884"><STRONG>1. Interactive Map Integration</STRONG></H4><UL><LI>Seamless integration with Google Maps to display real-time shipment routes.</LI><LI>Dynamic updates based on user input, such as shipment ID.</LI></UL><H4 id="toc-hId-746981379"><STRONG>2. Step-by-Step Directions</STRONG></H4><UL><LI>Instructions and distances for each step in the route.</LI><LI>Multilingual support to cater to global users.</LI></UL><H4 id="toc-hId-550467874"><STRONG>3. Shipment Search</STRONG></H4><UL><LI>Simple search functionality to retrieve shipment routes using shipment IDs.</LI></UL><H4 id="toc-hId-353954369"><STRONG>4. Real-Time Distance Calculation</STRONG></H4><UL><LI>Display total distance for the shipment route instantly.</LI></UL><H3 id="toc-hId-28358145"><STRONG>Setup Instructions</STRONG></H3><P><STRONG>Step 1: Configure Google Maps API</STRONG><BR />To integrate Google Maps, you need to set up an API key:</P><OL><LI><STRONG>Go to the <A target="_new" rel="noopener"><SPAN>Google</SPAN><SPAN> Developers</SPAN><SPAN> Console</SPAN></A></STRONG>.</LI><LI><STRONG>Create or select a project</STRONG>:<UL><LI>If you don’t have an existing project, create a new one.</LI></UL></LI><LI><STRONG>Enable Google Maps JavaScript API</STRONG>:<UL><LI>Search for "Google Maps JavaScript API" in the library and enable it.</LI></UL></LI><LI><STRONG>Create API Credentials</STRONG>:<UL><LI>Navigate to the "Credentials" page.</LI><LI>Generate a <STRONG>Browser Key</STRONG> for your application.</LI></UL></LI><LI><STRONG>Set API Restrictions</STRONG>:<UL><LI>Restrict the key to your application’s domain for security purposes.</LI></UL></LI></OL><P>Example API URL for integration:</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&amp;callback=initMap</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>Replace YOUR_API_KEY with the key generated in the Google Developers Console.&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="MahmoudFarag_1-1734988791435.png" style="width: 613px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204801i36295B4A359DC65F/image-dimensions/613x291?v=v2" width="613" height="291" role="button" title="MahmoudFarag_1-1734988791435.png" alt="MahmoudFarag_1-1734988791435.png" /></span></P><P><STRONG>Step 2: Configure OData Service</STRONG></P><UL><LI>Create an OData service with an entity set, e.g., <STRONG>ShipmentSet.</STRONG></LI><LI>Ensure the service fetches <STRONG>StartCoords&nbsp;</STRONG>and <STRONG>EndCoords&nbsp;</STRONG>based on the shipment number<STRONG>.</STRONG></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-json"><code>{ "StartCoords": { "lat": 30.0444, "lng": 31.2357 }, "EndCoords": { "lat": 31.2023, "lng": 29.9014 } }</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P><STRONG>XML View</STRONG></P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-markup"><code>&lt;mvc:View controllerName="shiptrack.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:l="sap.ui.layout"&gt; &lt;Page id="page" title="Shipment Tracker"&gt; &lt;VBox&gt; &lt;SearchField id="searchField" placeholder="Enter Shipment ID" search=".onFindShipment" /&gt; &lt;Text id="totalDistanceText" text="Total Distance: {route&gt;/distance}" /&gt; &lt;l:Splitter orientation="Horizontal" width="100%" height="500px"&gt; &lt;l:Splitter&gt; &lt;!-- Directions List --&gt; &lt;List id="directionsList" items="{route&gt;/steps}"&gt; &lt;CustomListItem&gt; &lt;VBox&gt; &lt;Text text="{route&gt;instruction}" /&gt; &lt;Text text="{route&gt;distance}" /&gt; &lt;/VBox&gt; &lt;/CustomListItem&gt; &lt;/List&gt; &lt;/l:Splitter&gt; &lt;l:Splitter&gt; &lt;!-- Map Container --&gt; &lt;Core:HTML id="mapContainer" width="70%" height="500px" /&gt; &lt;/l:Splitter&gt; &lt;/l:Splitter&gt; &lt;/VBox&gt; &lt;/Page&gt; &lt;/mvc:View&gt;</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><H4 id="toc-hId--39072641"><SPAN>Full Controller Code:</SPAN></H4><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>sap.ui.define([ "sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/ui/model/json/JSONModel" ], function (Controller, MessageToast, JSONModel) { "use strict"; return Controller.extend("shiptrack.controller.View1", { onInit: function () { this._map = null; this._directionsService = null; this._directionsRenderer = null; const oModel = new JSONModel({ steps: [], distance: "" }); this.getView().setModel(oModel, "route"); this._loadGoogleMaps().then(() =&gt; { this._initializeMap(); }).catch((error) =&gt; { console.error("Google Maps could not be loaded:", error); MessageToast.show("Unable to load Google Maps. Please try again later."); }); }, _loadGoogleMaps: function () { return new Promise((resolve, reject) =&gt; { if (typeof google !== "undefined" &amp;&amp; google.maps) { resolve(); return; } const script = document.createElement("script"); script.src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&amp;libraries=geometry"; script.async = true; script.defer = true; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); }, _initializeMap: function () { const mapContainer = this.byId("mapContainer").getDomRef(); this._map = new google.maps.Map(mapContainer, { center: { lat: 0, lng: 0 }, zoom: 2 }); this._directionsService = new google.maps.DirectionsService(); this._directionsRenderer = new google.maps.DirectionsRenderer({ map: this._map }); }, onFindShipment: function () { const shipmentId = this.byId("searchField").getValue(); if (!shipmentId) { MessageToast.show("Please enter a shipment ID."); return; } // Fetch shipment details using OData service. /* const oDataModel = this.getOwnerComponent().getModel(); // Replace with your OData model. oDataModel.read(`/ShipmentSet('${shipmentNumber}')`, { success: (data) =&gt; { const startCoords = data.StartCoords; const endCoords = data.EndCoords; this._displayRoute(startCoords, endCoords); }, error: (error) =&gt; { console.error("Failed to fetch shipment details:", error); MessageToast.show("Unable to retrieve shipment details."); } }); */ const startCoords = { lat: 30.0444, lng: 31.2357 }; const endCoords = { lat: 31.2023, lng: 29.9014 }; this._displayRoute(startCoords, endCoords); }, _displayRoute: function (startCoords, endCoords) { const request = { origin: startCoords, destination: endCoords, travelMode: google.maps.TravelMode.DRIVING }; const oModel = this.getView().getModel("route"); this._directionsService.route(request, (result, status) =&gt; { if (status === google.maps.DirectionsStatus.OK) { this._directionsRenderer.setDirections(result); const route = result.routes[0]; const distance = route.legs[0].distance.text; const steps = route.legs[0].steps.map((step) =&gt; ({ instruction: step.instructions.replace(/&lt;[^&gt;]+&gt;/g, ''), distance: step.distance.text })); oModel.setProperty("/steps", steps); oModel.setProperty("/distance", distance); MessageToast.show(`Total distance: ${distance}`); } else { MessageToast.show("Unable to retrieve directions."); } }); } }); });</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><H4 id="toc-hId--235586146"><STRONG>Final Demo Video</STRONG></H4><P>Watch the application in action:&nbsp;<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Shipment Tracking - App.gif" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204807i25C00FEBD091E8DD/image-size/large?v=v2&amp;px=999" role="button" title="Shipment Tracking - App.gif" alt="Shipment Tracking - App.gif" /></span></P><H3 id="toc-hId--561182370"><STRONG><BR />Conclusion</STRONG></H3><P>With the combination of SAPUI5 and Google Maps API, our Shipment Tracking Application delivers a powerful solution for real-time logistics management. By following the provided setup instructions and integrating the Google Maps API securely, you can create an efficient and user-friendly tool for your business.&nbsp;</P><P><SPAN>Feel free to implement this application in your SAP projects and customize it as per your needs.</SPAN><BR /><SPAN>Happy coding!&nbsp;<span class="lia-unicode-emoji" title=":winking_face:">😉</span></SPAN></P><P>&nbsp;</P> 2024-12-23T22:35:09.074000+01:00 https://community.sap.com/t5/technology-blogs-by-members/let-s-create-a-json-path-query-tool-in-sap-ui5-as-simple-as-possible/ba-p/13971232 Let's Create a JSON Path Query Tool In SAP UI5 As Simple as Possible 2024-12-24T12:50:17.368000+01:00 dibyajyoti_nanda https://community.sap.com/t5/user/viewprofilepage/user-id/184938 <P>Hello Everyone,</P><P>Most of us are aware about JSON and its significance in SAP UI5 for all the data handling, often its observed that we need a complex coding to manipulate the Json Data, so we are trying to address this by Query based program originally introduced by&nbsp;<A href="http://goessner.net/articles/JsonPath/" target="_blank" rel="nofollow noopener noreferrer"><STRONG>Stefan Goessner's original post</STRONG></A>&nbsp;and we will crate a tool around it.&nbsp;&nbsp;</P><P>A frequently emphasized advantage of&nbsp;XML&nbsp;is the availability of plenty tools to analyze, transform and selectively extract data out of XML documents.&nbsp;<A href="http://en.wikipedia.org/wiki/XPath" target="_blank" rel="nofollow noopener noreferrer">XPath</A>&nbsp;is one of these powerful tools.</P><P>It's time to wonder, if there is a need for something like XPath4JSON and what are the problems it can solve.</P><UL><LI>Data may be interactively found and extracted out of&nbsp;<A href="http://json.org/" target="_blank" rel="nofollow noopener noreferrer">JSON</A>&nbsp;structures on the client without special scripting.</LI><LI>JSON data requested by the client can be reduced to the relevant parts on the server, such minimizing the bandwidth usage of the server response.</LI></UL><P>If we agree, that a tool for picking parts out of a JSON structure at hand does make sense, some questions come up. How should it do its job? How do JSONPath expressions look like?</P><P>We will be using a library developed by &nbsp;<A href="http://goessner.net/articles/JsonPath/" target="_blank" rel="nofollow noopener noreferrer"><STRONG>Stefan Goessner's original post</STRONG></A>&nbsp;introducing JSONPath in 2007.</P><P>We will be developing a UI5 App using this library so that we can us the app for doing a query over a JSON object.</P><P>Skil Set Involved: - JSON, UI5, Java Script and Any SAP web Based tool (WEB IDE, BAS)</P><P>For a Quick Reference we can check below details</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_0-1735039061181.png" style="width: 620px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204924iAE60D0F3D11D5AA9/image-dimensions/620x488?v=v2" width="620" height="488" role="button" title="dibyajyoti_nanda_0-1735039061181.png" alt="dibyajyoti_nanda_0-1735039061181.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_1-1735039139335.png" style="width: 623px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204925i44F7763A9A0F1ABA/image-dimensions/623x491?v=v2" width="623" height="491" role="button" title="dibyajyoti_nanda_1-1735039139335.png" alt="dibyajyoti_nanda_1-1735039139335.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_2-1735039139339.png" style="width: 578px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204926i245078E0E41E7C6A/image-dimensions/578x561?v=v2" width="578" height="561" role="button" title="dibyajyoti_nanda_2-1735039139339.png" alt="dibyajyoti_nanda_2-1735039139339.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_3-1735039139343.png" style="width: 585px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204927iF31EA1A00F7E2C21/image-dimensions/585x405?v=v2" width="585" height="405" role="button" title="dibyajyoti_nanda_3-1735039139343.png" alt="dibyajyoti_nanda_3-1735039139343.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P>We will be developing a UI5 App using this library so that we can us the app for doing a query over a JSON object.</P><P>Skill Set Involved: - JSON, UI5, Java Script and Any SAP web Based tool (WEB IDE, BAS)</P><P>Once Application is developed, the application should look like below.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_4-1735039139348.png" style="width: 712px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204928i086A1E85268FFEFF/image-dimensions/712x299?v=v2" width="712" height="299" role="button" title="dibyajyoti_nanda_4-1735039139348.png" alt="dibyajyoti_nanda_4-1735039139348.png" /></span></P><P>Step1 :- Create a SAP UI5 Basic app by using template below structure</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_5-1735039139350.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204929iFB2325ABE4DD7566/image-size/medium?v=v2&amp;px=400" role="button" title="dibyajyoti_nanda_5-1735039139350.png" alt="dibyajyoti_nanda_5-1735039139350.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P>Step2: - we will be taking library reference from below URL, and I have modified as per my need.</P><P><A href="https://code.google.com/archive/p/jsonpath/downloads" target="_blank" rel="noopener nofollow noreferrer">https://code.google.com/archive/p/jsonpath/downloads</A></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_6-1735039139356.png" style="width: 637px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204930i274E8C79B9196BF9/image-dimensions/637x225?v=v2" width="637" height="225" role="button" title="dibyajyoti_nanda_6-1735039139356.png" alt="dibyajyoti_nanda_6-1735039139356.png" /></span></P><P>Seep3:- we will create a new folder ‘external’ and add &nbsp;a js file name ‘<STRONG>jsonpath.js’ </STRONG>and the content will be like below.</P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>/* JSONPath 0.8.0 - XPath for JSON * * Copyright (c) 2007 Stefan Goessner (goessner.net) * Licensed under the MIT (MIT-LICENSE.txt) licence. */ sap.ui.define([ "sap/m/library" ], function (mobileLibrary) { "use strict"; // shortcut for sap.m.URLHelper var URLHelper = mobileLibrary.URLHelper; return { jsonQuery: function (obj, expr, arg) { var P = { resultType: arg &amp;&amp; arg.resultType || "VALUE", result: [], normalize: function (expr) { var subx = []; return expr.replace(/[\['](\??\(.*?\))[\]']/g, function ($0, $1) { return "[#" + (subx.push($1) - 1) + "]"; }) .replace(/'?\.'?|\['?/g, ";") .replace(/;;;|;;/g, ";..;") .replace(/;$|'?\]|'$/g, "") .replace(/#([0-9]+)/g, function ($0, $1) { return subx[$1]; }); }, asPath: function (path) { var x = path.split(";"), p = "$"; for (var i = 1, n = x.length; i &lt; n; i++) p += /^[0-9*]+$/.test(x[i]) ? ("[" + x[i] + "]") : ("['" + x[i] + "']"); return p; }, store: function (p, v) { if (p) P.result[P.result.length] = P.resultType == "PATH" ? P.asPath(p) : v; return !!p; }, trace: function (expr, val, path) { if (expr) { var x = expr.split(";"), loc = x.shift(); x = x.join(";"); if (val &amp;&amp; val.hasOwnProperty(loc)) P.trace(x, val[loc], path + ";" + loc); else if (loc === "*") P.walk(loc, x, val, path, function (m, l, x, v, p) { P.trace(m + ";" + x, v, p); }); else if (loc === "..") { P.trace(x, val, path); P.walk(loc, x, val, path, function (m, l, x, v, p) { typeof v[m] === "object" &amp;&amp; P.trace("..;" + x, v[m], p + ";" + m); }); } else if (/,/.test(loc)) { // [name1,name2,...] for (var s = loc.split(/'?,'?/), i = 0, n = s.length; i &lt; n; i++) P.trace(s[i] + ";" + x, val, path); } else if (/^\(.*?\)$/.test(loc)) // [(expr)] P.trace(P.eval(loc, val, path.substr(path.lastIndexOf(";") + 1)) + ";" + x, val, path); else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)] P.walk(loc, x, val, path, function (m, l, x, v, p) { if (P.eval(l.replace(/^\?\((.*?)\)$/, "$1"), v[m], m)) P.trace(m + ";" + x, v, p); }); else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step] phyton slice syntax P.slice(loc, x, val, path); } else P.store(path, val); }, walk: function (loc, expr, val, path, f) { if (val instanceof Array) { for (var i = 0, n = val.length; i &lt; n; i++) if (i in val) f(i, loc, expr, val, path); } else if (typeof val === "object") { for (var m in val) if (val.hasOwnProperty(m)) f(m, loc, expr, val, path); } }, slice: function (loc, expr, val, path) { if (val instanceof Array) { var len = val.length, start = 0, end = len, step = 1; loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function ($0, $1, $2, $3) { start = parseInt($1 || start); end = parseInt($2 || end); step = parseInt($3 || step); }); start = (start &lt; 0) ? Math.max(0, start + len) : Math.min(len, start); end = (end &lt; 0) ? Math.max(0, end + len) : Math.min(len, end); for (var i = start; i &lt; end; i += step) P.trace(i + ";" + expr, val, path); } }, eval: function (x, _v, _vname) { try { return $ &amp;&amp; _v &amp;&amp; eval(x.replace(/@/g, "_v")); } catch (e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "_v").replace(/\^/g, "_a")); } } }; var $ = obj; if (expr &amp;&amp; obj &amp;&amp; (P.resultType == "VALUE" || P.resultType == "PATH")) { P.trace(P.normalize(expr).replace(/^\$;/, ""), obj, "$"); return P.result.length ? P.result : false; } } }; });</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>Step4 :- Modify the View1.xml Content for the required screen.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_7-1735039139359.png" style="width: 615px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204931iDC8E960C703646BF/image-dimensions/615x249?v=v2" width="615" height="249" role="button" title="dibyajyoti_nanda_7-1735039139359.png" alt="dibyajyoti_nanda_7-1735039139359.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-markup"><code>&lt;mvc:View controllerName="Test.TEST.controller.View1" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:code="sap.ui.codeeditor"&gt; &lt;Shell id="shell"&gt; &lt;App id="app"&gt; &lt;pages&gt; &lt;Page id="page" title="JSON Path Query Tool"&gt; &lt;content&gt; &lt;OverflowToolbar id="otb1"&gt; &lt;Button type="Accept" text="Execute" press="onExecutePress"/&gt; &lt;Button type="Accept" text="Template" press="onTemplatePress"/&gt; &lt;/OverflowToolbar&gt; &lt;!--&lt;Button text="ok" press=".onPress"&gt;&lt;/Button&gt;--&gt; &lt;Input id="inputText" placeholder="Enter Query" class="sapUiSmallMarginBottom"/&gt; &lt;code:CodeEditor id="inputTextCode" type="json" value='' height="200px"/&gt; &lt;TextArea id="idQueryOutput" editable="false" growingMaxLines="7" width="100%" height="50%"&gt;&lt;/TextArea&gt; &lt;/content&gt; &lt;/Page&gt; &lt;/pages&gt; &lt;/App&gt; &lt;/Shell&gt; &lt;/mvc:View&gt;</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>Step5:- View1.controller.js</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_8-1735039139364.png" style="width: 514px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204932i4D7B3079D3443BA6/image-dimensions/514x416?v=v2" width="514" height="416" role="button" title="dibyajyoti_nanda_8-1735039139364.png" alt="dibyajyoti_nanda_8-1735039139364.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dibyajyoti_nanda_9-1735039139367.png" style="width: 601px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204933iE5037F24DAA3A2DC/image-dimensions/601x506?v=v2" width="601" height="506" role="button" title="dibyajyoti_nanda_9-1735039139367.png" alt="dibyajyoti_nanda_9-1735039139367.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>sap.ui.define([ "sap/ui/core/mvc/Controller", "../external/jsonpath", "sap/ui/model/json/JSONModel" ], function (Controller, jsonpath, JSONModel) { "use strict"; return Controller.extend("Test.TEST.controller.View1", { onInit: function () { }, onExecutePress: function () { var codeEditorData = JSON.parse(this.getView().byId("inputTextCode").getValue()); this.getView().setModel(new JSONModel(codeEditorData), "codeEditorDataModel"); var queryString = this.getView().byId("inputText").getValue().trim(); var productNames = jsonpath.jsonQuery(codeEditorData, queryString); this.getView().byId("idQueryOutput").setValue(productNames); }, onTemplatePress: function () { var jsonData = { "store": { "book": [{ "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 }], "bicycle": { "color": "red", "price": 19.95 } } }; this.getView().byId("inputTextCode").setValue(JSON.stringify(jsonData)); this.getView().byId("inputText").setValue("$.store.book[*].author"); } }); });</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>Regards,</P><P>Dibyajyoti Nanda</P><P><A href="https://www.linkedin.com/in/dibyajyoti-nanda-23907429/" target="_blank" rel="nofollow noopener noreferrer">https://www.linkedin.com/in/dibyajyoti-nanda-23907429/</A></P> 2024-12-24T12:50:17.368000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-3/ba-p/13976027 Designing UI5 Apps as Business Solution for SAP Build Work Zone - Part 3 2025-01-08T16:13:07.296000+01:00 matthias_schmalz https://community.sap.com/t5/user/viewprofilepage/user-id/196501 <H1 id="toc-hId-949445568">Content Navigation</H1><P><STRONG>Part 1:</STRONG> <A href="https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-1/ba-p/13923459" target="_blank">A simple UI5 app that runs in the SAP Build Work Zone Service</A><BR /><BR /><STRONG>Part 2: </STRONG><A href="https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-2/ba-p/13929148" target="_self">Multiple Apps with a Shared Reuse Library</A><BR /><BR /><STRONG>Part 3:</STRONG>Splitting bigger projects <STRONG>(Current post)</STRONG><BR /><BR /><STRONG>Part 4:</STRONG>Advanced splits <STRONG>(Planned)</STRONG></P><H1 id="toc-hId-752932063">Splitting Bigger Projects</H1><P>In the <A href="https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-2/ba-p/13929148" target="_blank">last posts</A>, you have learnt how to build multiple apps and move common parts of them into a reusable library. Everything is deployed using one <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-multiple-apps/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">MTA</A>.<BR />In this part, we will have a look at how to split this into smaller parts. This enables us to have independent lifecycles and helps distribute responsibilities between different developer groups.<BR />For example, the reusable library might have a different lifecycle than the apps and is not changed frequently. Maybe they are also maintained by other developers and should be stored in a separate Git repository.&nbsp;<BR /><BR />The sample code can be found in the&nbsp;<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples" target="_blank" rel="noopener nofollow noreferrer">GitHub repository</A>.</P><H2 id="toc-hId-685501277">Current State</H2><P>Let us have a quick look at the starting point. There are three HTML5 apps, which are all deployed to the same app-host. There is one XSUAA and one set of runtime/design-time destinations for the integration into SAP Build Work Zone. All <I>sap.cloud/service</I> names in manifest.json files ([<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-multiple-apps/lib/src/manifest.json#L26" target="_blank" rel="noopener nofollow noreferrer">Shared</A>], [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-multiple-apps/app1/webapp/manifest.json#L153" target="_blank" rel="noopener nofollow noreferrer">App1</A>], [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-multiple-apps/app2/webapp/manifest.json#L152" target="_blank" rel="noopener nofollow noreferrer">App2</A>]) are the same and the <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-multiple-apps/mta.yaml#L24C78-L24C107" target="_blank" rel="noopener nofollow noreferrer">DT destination refers to it as well</A>:</P><PRE>"sap.cloud": { "public": true, "service": "<STRONG>btp.samples.cdm.multiple.apps</STRONG>" }</PRE><PRE>URL: https://html5-apps-repo-rt.${default-domain}/applications/cdm/<STRONG>btp.samples.cdm.multiple.apps</STRONG></PRE><P>In their manifest.json the apps declare a dependency to the reuse library ([<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-multiple-apps/app1/webapp/manifest.json#L73" target="_blank" rel="noopener nofollow noreferrer">App1</A>], [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-multiple-apps/app2/webapp/manifest.json#L72" target="_blank" rel="noopener nofollow noreferrer">App2</A>]).</P><PRE>"sap.ui5": { "dependencies": { "libs": { "btp.samples.cdm.multiple.apps.lib": {} ...</PRE><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_0-1736262495050.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209103i7F670693C1871D92/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_0-1736262495050.png" alt="matthias_schmalz_0-1736262495050.png" /></span></P><P>&nbsp;</P><P>The corresponding <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-multiple-apps/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">MTA</A> looks like this:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_1-1736262512037.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209104iC0352485CFB37BE9/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_1-1736262512037.png" alt="matthias_schmalz_1-1736262512037.png" /></span></P><P>&nbsp;</P><H2 id="toc-hId-488987772">A First Split for the App-Hosts</H2><P>The first split you would do, is to use multiple HTML5 app-hosts and distribute the HTML5 apps to them.<BR />Since this is an intermediate step, there is no sample code available.</P><H3 id="toc-hId-421556986">Deployment</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_2-1736262529251.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209105iD2BA7B9996AD9538/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_2-1736262529251.png" alt="matthias_schmalz_2-1736262529251.png" /></span></P><P>&nbsp;</P><P>Both apps are moved to their own app-host while the shared library stays on the previously used app-host. If you have more apps, you can distribute them across app-hosts as needed.<BR />Every app-host is connected to the same XSUAA and all apps on the app-hosts use the same cloud service name, specified by the DT destination.<BR />There are no changes for the apps themselves and for the content of the cdm.json.<BR />For now, the cdm.json remains on the shared app-host. In be consistent, the shared app-host additionally depends on the app-hosts with the consuming apps.<BR />This way the platform understands that the content of these app-hosts is relevant for the content of the cdm.json and that the apps which are specified inside can be found and the library dependencies of the apps can be resolved as well.</P><H3 id="toc-hId-225043481">MTA</H3><P>The corresponding MTA would look like this:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_3-1736262548988.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209106iB60BCCEE95277596/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_3-1736262548988.png" alt="matthias_schmalz_3-1736262548988.png" /></span></P><P>&nbsp;</P><P>There are now three managed resources for the app-hosts and Three HTML5 app content deployers. The deployer of the shared app-host additionally requires the app-hosts of the apps. This will establish the needed dependencies between them and binds them together.</P><H3 id="toc-hId-28529976">Problems</H3><P>Only splitting the app-hosts as we have done until now does not add real value because everything is still contained in one MTA.<BR />It's also not ideal that the shared app-host depends on the app-hosts containing the apps. A successful deployment requires to first deploy the apps and then the shared app-host. Otherwise, the contained CDM would not be consistent.<BR />You might have noticed that there is even a circular dependency because the apps itself depend on the shared library.<BR />Nevertheless, it is a good starting point for the next step.</P><H2 id="toc-hId--297066248">Split the CDM Model</H2><P>We are now going to split the cdm.json. With this, we can avoid the bad structuring of dependencies and the circular dependencies between the app-hosts caused by the single shared cdm.json. This will also inverse the dependencies.<BR />Since this is an intermediate step, there is no sample code available.</P><H3 id="toc-hId--364497034">Deployment</H3><P>The new deployment would look like this:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_4-1736262567206.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209107iCA34455DDF287CCD/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_4-1736262567206.png" alt="matthias_schmalz_4-1736262567206.png" /></span></P><P>&nbsp;</P><P>We now have a cdm.json on all three app-hosts ([<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-shared/workzone/cdm.json" target="_blank" rel="noopener nofollow noreferrer">Shared</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-app1/workzone/cdm.json" target="_blank" rel="noopener nofollow noreferrer">App1</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-app2/workzone/cdm.json" target="_blank" rel="noopener nofollow noreferrer">App2</A>]). The shared cdm.json contains common definitions. The two app-specific ones extend them by adding the apps. Because all three app-hosts have the same sap.cloud/service, which is specified in the DT destination, they will all be merged together. We will take a closer look at this below.<BR />Note that now the dependencies between the app-hosts have been inverted and the app-hosts holding the apps depend on the shared app-host. There is no longer one leading app-host which binds them all together but independent groups which are still consistent. For example, app-host 1 is bound together with the shared app-host. Therefore, the cdm.json of app-host 1 can find the defined app 1 and the library dependency of the app can be resolved. However, the cdm.json of app-host 1 cannot refer to app 2, because the app-host containing is not bound to it.<BR />This way you achieve good isolation between independent applications.</P><H3 id="toc-hId--561010539">MTA</H3><P>The corresponding MTA would look like this:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_5-1736262583458.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209108i31767373A24D61EC/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_5-1736262583458.png" alt="matthias_schmalz_5-1736262583458.png" /></span></P><P>There is only a slight change in the requirements of the HTML5 app deployer. Now the deployer modules for the apps require the shared app-host, whereas the shared module deployer no longer requires the app-hosts of the apps.</P><H3 id="toc-hId--832755413">How to split the cdm.json</H3><P>Before we split the CDM model into multiple parts we must understand how it is structured. In the CDM model, we have different types of entities like catalogs, groups, and roles.<BR />They all have some header attributes like an ID, a translatable title, and a description. Additionally, they have references to other entities or apps. E.g., catalogs and groups refer to the tiles of the included apps (which is defined in the app manifest). Roles also refer to the contained apps as well as to the contained groups and catalogs.<BR />For the full CDM model please refer to <A href="https://help.sap.com/docs/build-work-zone-standard-edition/sap-build-work-zone-standard-edition/creating-cdm-json-file-for-multi-tenancy-html5-app" target="_blank" rel="noopener noreferrer">About the Common Data Model</A>.<BR />When splitting the model there can be different cases:</P><UL><LI>If the CDM Models of your apps are completely independent of each other, which means they have their own roles catalogs and groups, you can just move them accordingly.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_6-1735917985864.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/207289iFFDD0A40390F5DF2/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_6-1735917985864.png" alt="matthias_schmalz_6-1735917985864.png" /></span></LI><LI>However, in most cases you want to have common entities or even just one catalog, role and group which contain all apps.<BR />In this case you can split the definition of the entities across the different cdm.json file. E.g. The shared cdm.json just describes the connection of role, catalog, and group and the cdm.json of the apps describe that the app is contained there. The platform will merge them together.<BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_7-1735918009999.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/207290i26692004507AC80A/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_7-1735918009999.png" alt="matthias_schmalz_7-1735918009999.png" /></span></LI></UL><P>The merge of cdm.json files will collect the entities of all files. Then it will match them by type and ID and merge the matching ones by merging their references.<BR /><STRONG>However, there is currently an inconvenient limitation:</STRONG><BR />While the merge works fine for references, for simple header attributes like the title and description it will pick one of the matched entities randomly and take its definition. This means that currently the header definitions of the split entities must be exactly the same in all cdm.json files to avoid unpredictable behavior.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_8-1735918046803.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/207291iD27291A22C4D051D/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_8-1735918046803.png" alt="matthias_schmalz_8-1735918046803.png" /></span></P><P>In the samples the 2nd case has been modeled in the [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-shared/workzone/cdm.json" target="_blank" rel="noopener nofollow noreferrer">shared cdm.json</A>], [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-app1/workzone/cdm.json" target="_blank" rel="noopener nofollow noreferrer">app1 cdm.json</A>] and [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-app2/workzone/cdm.json" target="_blank" rel="noopener nofollow noreferrer">app2 cdm.json</A>] (The links refer to the sample of the next split)</P><P>&nbsp;</P><H3 id="toc-hId--1029268918">How to verify the final CDM model</H3><P>You might want to verify how the final MTA of your solution looks like and whether the CDM content has been merged as you expect.<BR />After you have deployed the MTAs, you can access it the same way as SAP Build Work Zone will do it, which is configured in the design-time destination.<BR />You will need an HTTP REST client to do this. SAP Business Application Studio or MS Visual Studio Code provide a <A href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client" target="_blank" rel="noopener nofollow noreferrer">REST Client extension</A> which is installed by default.</P><P>You can find the created design-time destination in the BTP Cockpit in your sub account under Connectivity -&gt; Destinations.<BR />Here you will find the target URL which looks as follows:<BR /><A href="https://html5-apps-repo-rt.cfapps" target="_blank" rel="noopener nofollow noreferrer">https://html5-apps-repo-rt.cfapps</A>.<I>&lt;landscape domain&gt;</I>.hana.ondemand.com/applications/cdm/<I>&lt;sap.cloud/service name&gt;</I><BR />The destination also specifies everything that is needed to obtain an access token. This information is taken from a service key of the HTML5 app-runtime instance. It consists of</P><UL><LI>a token URL which looks like<BR />https://<I>&lt;subaccount domain&gt;</I>.authentication.<I>&lt;landscape domain&gt;</I>.hana.ondemand.com/oauth/token</LI><LI>a client ID</LI><LI>a client secret. You will not be able to retrieve the client secret from the destination, therefore you must retrieve this from the service key of the app-runtime instance instead.</LI></UL><P>To retrieve the CDM model you have to first retrieve an access token from the token URL using the client credentials and then use the token to call the target URL.<BR />The following code can be used in the REST Client extension to do this:</P><PRE># @name getToken<BR /> GET https://<I>&lt;subaccount domain&gt;</I>.authentication.<I>&lt;landscape domain&gt;</I>.hana.ondemand.com/oauth/token?grant_type=client_credentials HTTP/1.1 <BR /> Authorization: Basic <I>&lt;client ID&gt;</I>:<I>&lt;client secret&gt;</I><BR /><BR /> ###<BR /><BR /> GET https://html5-apps-repo-rt.cfapps.<I>&lt;landscape domain&gt;</I>.hana.ondemand.com/applications/cdm/<I>&lt;sap.cloud/service name&gt;</I> HTTP/1.1<BR /> Authorization: Bearer {{getToken.response.body.$.access_token}} </PRE><P>The response will provide the fully merged CDM model of your solution. It also includes more information about the contained apps and their visualizations which is derived from the defined navigation inbounds in the manifest.json.</P><H3 id="toc-hId--1225782423">Problems</H3><P>We have now solved the bad structuring of dependencies, but still everything is contained inside a single MTA file.</P><H2 id="toc-hId--1128892921">Split the MTAs</H2><P>In the next step, we will split the single MTA into multiple ones.<BR />The sample code can be found <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/tree/main/btp-samples-cdm-split-mta" target="_blank" rel="noopener nofollow noreferrer">here</A></P><H3 id="toc-hId--1618809433">Deployment</H3><P>Every app and app-host will be moved to a separate MTA. The XSUAA and the destination service will still be shared by all and therefore move to the MTA containing the shared library. The result of the deployment will not change at all. Below, the colors indicate which MTA will deploy which content.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_6-1736262609990.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209109iC5D65011EDF08B54/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_6-1736262609990.png" alt="matthias_schmalz_6-1736262609990.png" /></span></P><P>The cloud service name will still be the same everywhere.</P><H3 id="toc-hId--1815322938">MTAs</H3><P>The MTAs [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-shared/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">Shared</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-app1/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">App1</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-mta/mta-app2/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">App2</A>] will look like this.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_7-1736262628257.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209110iAA80775B37D8D8A1/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_7-1736262628257.png" alt="matthias_schmalz_7-1736262628257.png" /></span></P><P>Note that the XSUAA service and the shared app-host resources in the app <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-split-mta/mta-app1/mta.yaml#L54" target="_blank" rel="noopener nofollow noreferrer">MTAs</A> are of the type "existing service". Only the shared <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/b0b6e952542c8db27b351b386708726e6b8f7ffc/btp-samples-cdm-split-mta/mta-shared/mta.yaml#L77" target="_blank" rel="noopener nofollow noreferrer">MTA</A> defines it as a "managed service" because this MTA owns the service instance and will create it. Therefore, the <STRONG>shared MTA must be deployed first</STRONG>.<BR /><BR />This setup already fulfils most use cases. The apps and shared library can now be developed and deployed <STRONG>independently</STRONG>. They can also be moved to different Git repositories.</P><H2 id="toc-hId--1718433436">Split the XSUAAs</H2><P>Until now, the MTA projects are already quite independent, but they still share the same XSUAA and the contained authorization objects. However, your apps might contain complex back-end services and have complex authorization objects. In that case, developers would not want to maintain the xs-security.json files in the central MTA but move the app-specific parts to the MTA of the app. This is a good reason to split the XSUAAs.</P><H3 id="toc-hId-2086617348">Deployment</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_8-1736262646299.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209111i9C5F97FC485451DA/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_8-1736262646299.png" alt="matthias_schmalz_8-1736262646299.png" /></span></P><P>Now we have three XSUAA instances. Each one is deployed by one MTA. Each app-host binds against its corresponding XSUAA instance. This way the authorization handling is bound to the correct XSUAA, and its authorization model applies. Example: If you have routes in xs-app.json that require a given scope, they are defined by the corresponding XSUAA. The same would happen for any back-end apps that are possibly contained in your MTA.<BR /><STRONG>Previously</STRONG> the connection between the app-host and the XSUAAwas based on the cloud service name. Therefore, in <A href="https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-for-sap-launchpad-service-part-3/ba-p/13513569" target="_blank">the former version of this blog</A> it has been necessary to split the cloud service name at this point. This is no longer needed here and even has a different effect, which is needed for splitting the service provider.<BR /><BR /></P><P>The MTAs [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-xsuaa/mta-shared/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">Shared</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-xsuaa/mta-app1/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">App1</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-xsuaa/mta-app2/mta.yaml" target="_blank" rel="noopener nofollow noreferrer">App2</A>] will look like this:</P><H3 id="toc-hId-1890103843">MTAs</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matthias_schmalz_9-1736262663515.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/209112i654372C2D96A4736/image-size/large?v=v2&amp;px=999" role="button" title="matthias_schmalz_9-1736262663515.png" alt="matthias_schmalz_9-1736262663515.png" /></span></P><P>Every MTA now contains its own xs-security.json [<A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-xsuaa/mta-shared/xs-security.json#L2" target="_blank" rel="noopener nofollow noreferrer">Shared</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-xsuaa/mta-app1/xs-security.json#L2" target="_blank" rel="noopener nofollow noreferrer">App1</A>, <A href="https://github.com/SAP-samples/btp-launchpad-ui-samples/blob/main/btp-samples-cdm-split-xsuaa/mta-app2/xs-security.json#L2" target="_blank" rel="noopener nofollow noreferrer">App2</A>] with its own unique <I>xsappname</I>.</P><H2 id="toc-hId-1986993345">Next Steps</H2><P>Now you know about the most relevant splits for your use cases.<BR />A more advanced use case which also requires splitting the destination service instance is described in <A target="_self">Part 4 of this blog.</A></P> 2025-01-08T16:13:07.296000+01:00 https://community.sap.com/t5/application-development-blog-posts/sap-developer-news-january-9th-2025/ba-p/13981822 SAP Developer News, January 9th, 2025 2025-01-09T21:00:00.041000+01:00 thomas_jung https://community.sap.com/t5/user/viewprofilepage/user-id/139 <P><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FzS2ZHfwxACk%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DzS2ZHfwxACk&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FzS2ZHfwxACk%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="400" height="225" scrolling="no" title="HANA Cloud 2024/Q4, Open Source Report, UI5 Web Components 2.0, CAP Plugins | SAP Developer News" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><STRONG>Podcast Version</STRONG>: <A href="https://podcast.opensap.info/sap-developers/2025/01/09/sap-developer-news-january-9th-2025/" target="_blank" rel="nofollow noopener noreferrer">https://podcast.opensap.info/sap-developers/2025/01/09/sap-developer-news-january-9th-2025/</A></P><H3 id="toc-hId-1208393255">DESCRIPTION</H3><P><STRONG>Welcome to 2025</STRONG></P><P><STRONG>Mastering SAP S/4HANA Extension with SAP Build- Discovery center mission</STRONG></P><UL><LI>New Discovery Center mission for SAP Build: <SPAN><A href="https://discovery-center.cloud.sap/missiondetail/4420/4706/" target="_blank" rel="nofollow noopener noreferrer">https://discovery-center.cloud.sap/missiondetail/4420/4706/</A></SPAN></LI><LI>BTP Discovery Center: <SPAN><A href="https://discovery-center.cloud.sap/" target="_blank" rel="nofollow noopener noreferrer">https://discovery-center.cloud.sap/</A></SPAN></LI></UL><P><STRONG>What’s New in SAP HANA Cloud 2024/Q4</STRONG></P><UL><LI>What’s New in SAP HANA Cloud – December 2024: <A href="https://community.sap.com/t5/technology-blogs-by-sap/what-s-new-in-sap-hana-cloud-december-2024/ba-p/13967275" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/what-s-new-in-sap-hana-cloud-december-2024/ba-p/13967275</A></LI><LI>New Machine Learning and NLP features in SAP HANA Cloud 2024 Q4: <A href="https://community.sap.com/t5/technology-blogs-by-sap/new-machine-learning-and-nlp-features-in-sap-hana-cloud-2024-q4/ba-p/13953934" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/new-machine-learning-and-nlp-features-in-sap-hana-cloud-2024-q4/ba-p/13953934</A></LI><LI>Calculation View Features of 2024 QRC4: <A href="https://community.sap.com/t5/technology-blogs-by-sap/calculation-view-features-of-2024-qrc4/ba-p/13965370" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/calculation-view-features-of-2024-qrc4/ba-p/13965370</A></LI></UL><P><STRONG>SAP Open Source Report 2024</STRONG></P><UL><LI>Blog post “A year of Collaboration and Innovation: SAP Open Source Report 2024”: <A href="https://community.sap.com/t5/technology-blogs-by-sap/a-year-of-collaboration-and-innovation-sap-open-source-report-2024/ba-p/13978967" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/a-year-of-collaboration-and-innovation-sap-open-source-report-2024/ba-p/13978967</A></LI><LI>SAP Open Source Report 2024: <A href="https://d.dam.sap.com/a/wxgtG2E/SAP%20Open%20Source%202024%20Report.pdf" target="_blank" rel="noopener noreferrer">https://d.dam.sap.com/a/wxgtG2E/SAP%20Open%20Source%202024%20Report.pdf</A></LI></UL><P><STRONG>Video: UI5 Web Components 2.0</STRONG></P><UL><LI><A href="https://www.youtube.com/watch?v=1ERrvS5-MpM" target="_blank" rel="nofollow noopener noreferrer">https://www.youtube.com/watch?v=1ERrvS5-MpM</A></LI></UL><P><STRONG>CAP Node.js Plugins live stream mini-series</STRONG></P><UL><LI>The series post with all the links to the live streams, recordings and blog posts: <A href="https://qmacro.org/blog/posts/2024/12/30/cap-node.js-plugins/" target="_blank" rel="nofollow noopener noreferrer">https://qmacro.org/blog/posts/2024/12/30/cap-node.js-plugins/</A></LI></UL><H3 id="toc-hId-1011879750">CHAPTER TITLES</H3><P>0:00 Intro</P><P>0:10 Welcome to 2025</P><P>1:35 Discovery center mission “Mastering SAP S/4HANA Extension with SAP Build”</P><P>2:39 What’s New in SAP HANA Cloud 2024/Q4</P><P>4:46 SAP Open Source Report 2024</P><P>5:35 Video: UI5 Web Components 2.0</P><P>5:59 CAP Node.js Plugins live stream mini-series</P><H3 id="toc-hId-815366245">Transcription</H3><P><STRONG>[Intro]</STRONG> This is the SAP Developer News for January 9th, 2025.</P><P><STRONG>[Thomas]</STRONG> Welcome everybody to the developer news in 2025. We've got more of the same great little newsbytes coming your way every week. We want to keep you up to date on what's going on in the SAP world for all of our developer ecosystem. But we also have some great new things planned for this year. We're going to continue with the CodeJams, of course. We want to bring up. Bring more road shows to areas that we've not been able to visit in the past couple years. We also will continue the TechEd on Tour, bringing the TechEd in-person experience to more locations near you. Be on the lookout for some of those locations announced probably about mid-year because most of that will happen in the fourth quarter of this year. And we've got some fun new things planned for the developer challenges this year as well. Already by mid-January, so in another week or so, you'll be able to try out the new SAP Community Escape Room Challenge. Can't wait for you to see what fun that's going to be. We've got some other great new things planned as well. We've got some new CodeJams on advanced topics that we're working on, and we'll continue to bring you all the same great experiences on the SAP developers YouTube channel that you've come to expect. So we look forward toa great 2025 with you.</P><P><STRONG>[Rekha]</STRONG> Hello, everybody. Are you using SAP BTP or have plans to use SAP BTP in the future, then SAP BTP Discovery Center website is a must-know resource. The Discovery Center has missions with use cases, step-by-step guides, reference architecture, SAP BTPs related details, and information related to newly added SAP Business AI features. A new mission called mastering SAP S/4HANA extensions with SAP Build has been made available in the Discovery Center. Here you find the use case, managing incident reporting and resolution, the SAP BTP services and components that are required to realize this use case. You also get access to SAP expert support and SAP community support while learning about this mission. Do check this out on the Discovery Center. Links are provided in the description box. Keep learning. Thank you.</P><P><STRONG>[Witalij]</STRONG> During the holiday season, I celebrated my birthday on December 23rd. And the SAP HANA product team marked the occasion with a special surprise for me and every one of you, the Q4, 24 release of a SAP HANA Cloud. This release brings a host of features designed to benefit data scientists, developers, and AI engineers alike. The Q42024 release introduces native multi-tenancy at the database level. This allows customer data to be managed in database tenants that share the same database instance while remaining logically separated. Multi-tenancy capability ensures enterprise-grade qualities at the tenant level, including customer-specific encryption, recovery, and resource isolation. With every quarterly release, the SAP HANA Cloud predictive analytics library, or PAL, has been enhanced with new embedded machine learning AI and NLP functions. Key highlights of this release include the introduction of text analysis and text authorization, as well as expanded support for vector data as input for additional machine learning functions such as classification and regression. Among the new calculation view features, the graphical expression editor null offers vector functions as well, such as causal similarity to calculate the similarity between the vectors, as well as the function to create a vector embedding from the text, using the vector embedding function obviously. The new SPL plan advisor enables the identification of performance issues in deviating SQL statements. It detects and optimizes SQL performance by comparing execution engine plans. By automatically testing and comparing execution performance across different plans, the advisor recommends and applies optimized execution plans for improved SQL performance. As always, be sure to check the blog posts from SAP Product Managers for all the details. Links are provided in the description. Wishing you a peaceful 2025. Bye. Bye.</P><P><STRONG>[DJ]</STRONG> 2024 was a great year for SAP and the Open Source Program Office and their activities. They've just published the Open Source Program Office and their activities. the SAP Open Source Report 24, which has some great insights as well as listing many of their accomplishments. And having read that report myself, I come away with the key concepts being all about people, community, commitment and collaboration. Basically, it's all about working together in the ecosphere. Anyway, there's a blog post from Ulrika about. the report and also the report itself linked both in the description. Happy reading.</P><P><STRONG>[Nico]</STRONG> Hi everyone and welcome to the SAP developer news. You would like to point your attention to a cool video from the UI5 core team about the UI5 Web Components 2.x release, including the new popover API, new AI components, and the enhanced toolkit. So go check it out and hope to see you soon.</P><P><STRONG>[DJ]</STRONG> We just wanted to let you know that right now we're running a new three-part live stream series on the Hands on SAP Dev show on our YouTube channel, all about CAP Node.js plugins. We had part one last week, which was all about understanding how the plug-in mechanism works. Part two is this week where we learn to all about understanding how the plug-in mechanism works. introspect our service in the CDS repel and the final part three is next week where we actually use the knowledge we've gained in the first two parts and write our plugin. Anyway, there's a link to a series post in the description to this video. In that series post there are links to the live streams, the replays and also to the accompanying blog posts. See you online. Thank you.</P> 2025-01-09T21:00:00.041000+01:00 https://community.sap.com/t5/technology-blogs-by-sap/sap-developer-challenge-sap-community-escape-house-ui5/ba-p/13982639 SAP Developer Challenge - SAP Community Escape House - UI5 2025-01-13T00:00:00.016000+01:00 nicoschoenteich https://community.sap.com/t5/user/viewprofilepage/user-id/898 <P><EM>The new year starts with a brand new SAP Developer Challenge! The Developer Advocates have created the <A href="https://sap-community-escape-house.cfapps.us10.hana.ondemand.com" target="_blank" rel="noopener noreferrer">SAP Community Escape House</A> - a virtual escape house (consisting of multiple rooms) that you can play in your browser. Read on for all the details.</EM></P><P>SAP Developer Challenges are all about having fun, trying new things, and learning along the way. You can also earn a badge in the SAP Community upon successful completion. For this year, all SAP Developer Challenges will happen in the <A href="https://sap-community-escape-house.cfapps.us10.hana.ondemand.com" target="_blank" rel="noopener noreferrer">SAP Community Escape House</A>. For each challenge we will unlock a new room in the house, and they all have a specific focus topic. Completing a challenge means successfully escaping the room by solving a series of coding-related tasks. The first room we unlocked for January (see schedule below) is about <A href="https://ui5.sap.com/" target="_self" rel="noopener noreferrer">UI5</A>, more specifically about how to scaffold a UI5 application using the command line.<EM><BR /></EM></P><P>&nbsp;</P><H1 id="toc-hId-950255724">How to participate</H1><P>Visit the <A href="https://sap-community-escape-house.cfapps.us10.hana.ondemand.com" target="_blank" rel="noopener noreferrer">SAP Community Escape House</A> and enter your numeric SAP Community user ID. If you don't know your user ID, go to your SAP Community profile. You can find the numeric ID at the end of the URL.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="2025-01-10_12-59-37.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210644i6A8DE5105EF0BDD3/image-size/large?v=v2&amp;px=999" role="button" title="2025-01-10_12-59-37.png" alt="2025-01-10_12-59-37.png" /></span></P><P>&nbsp;Once you see the SAP Community Escape House, select the UI5 room and start exploring it.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="2025-01-10_13-01-57.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210649i59D0107F614B54E0/image-size/large?v=v2&amp;px=999" role="button" title="2025-01-10_13-01-57.png" alt="2025-01-10_13-01-57.png" /></span></P><P><SPAN>The user interface of an escape room includes the room itself as well as a terminal. You can click the objects in the room to receive tips. Like in a real (physical) escape room, you will have to try out a few things and explore the room until you receive helpful tips and eventually instructions. These tips and instructions are printed in the terminal next to the room. The terminal is also used to submit solutions to tasks. Read the instructions you receive carefully to understand how.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="2025-01-10_13-02-11.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210648i3DE9E1555455519A/image-size/large?v=v2&amp;px=999" role="button" title="2025-01-10_13-02-11.png" alt="2025-01-10_13-02-11.png" /></span></P><P><SPAN>If you successfully escape the room (you will know when that happens), you will receive a badge in the SAP Community. We will assign the badges once the challenge closes.</SPAN></P><P>&nbsp;</P><H1 id="toc-hId-753742219">The schedule</H1><P>The UI5 room was unlocked on January 13th and will stay unlocked until the end of the year. However, the challenge closes on January 31st, so you will have to escape the room until then to qualify for a badge. Unlike the previous year, this SAP Developer Challenge does not consist of weekly sub-challenges. The next room (next challenge) will be unlocked in February.</P><P><STRONG>Good luck and happy escaping!</STRONG></P> 2025-01-13T00:00:00.016000+01:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-january-2025-issue-32/ba-p/13984589 SAP Fiori development newsletter January 2025 (issue #32) 2025-01-13T21:39:55.968000+01:00 PeterSpielvogel https://community.sap.com/t5/user/viewprofilepage/user-id/543 <P>Happy New Year!</P><P>Based on what we are seeing in the early days of the year, it promises to be a busy one. SAP is continuing to roll out more AI tools to make it easier to develop applications. To keep you informed, we have our first SAP Fiori Innovation Day of 2025 in Palo Alto on February 5.<BR /><A href="https://events.sap.com/sap-fiori-innovation-day-2025/en/home" target="_blank" rel="noopener noreferrer">https://events.sap.com/sap-fiori-innovation-day-2025/en/home</A><BR />If you cannot attend, we will have more events in other locations during the year.</P><P>For ongoing updates, I encourage you to join our monthly SAP Fiori development roundtable. You can meet online with&nbsp;fellow developers and the SAP engineers who build our professional development tools.&nbsp;<A href="https://docs.google.com/forms/d/1ZqIX3zzGBOOIqehmlIRz_HhpQEhqunkLSzN1gnaOwP8/edit" target="_blank" rel="noopener nofollow noreferrer">Register online</A> or email me for an invitation.&nbsp;Our next meeting is Wednesday, February 12, 2025.&nbsp;</P><P>If you prefer to receive this in your inbox, please&nbsp;<A href="https://www.sap.com/cmp/nl/sap-fiori-development-newsletter/index.html" target="_blank" rel="noopener noreferrer">subscribe to the SAP Fiori development newsletter.</A></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PeterSpielvogel_0-1736800681797.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/211527i2E7DF0D8AB973C52/image-size/large?v=v2&amp;px=999" role="button" title="PeterSpielvogel_0-1736800681797.png" alt="PeterSpielvogel_0-1736800681797.png" /></span></P><P>&nbsp;</P><P><STRONG>Development News</STRONG></P><P><STRONG>SAP Fiori tools 2411 update: enhanced full-stack development, AI integration, and more open source </STRONG></P><P>The latest release of SAP Fiori tools introduces several new features that bring together frontend and backend development, expand AI-driven capabilities, and further our journey towards open-source integration. Here’s a look at what’s new and what you can expect.</P><P><A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-tools-2411-update-enhanced-full-stack-development-ai-integration/ba-p/13929515" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-tools-2411-update-enhanced-full-stack-development-ai-integration/ba-p/13929515</A></P><P><STRONG>SAP Fiori tools 2501 update: elevating development with AI, usability, and flexibility </STRONG></P><P>The latest enhancements in SAP Fiori tools focus on leveraging AI, simplifying the user interface for adaptations, and improving the overall usability of the tools. This post explains what they mean for your SAP Fiori development experience.</P><P><A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-tools-2501-update-elevating-development-with-ai-usability-and/ba-p/13968245" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-tools-2501-update-elevating-development-with-ai-usability-and/ba-p/13968245</A></P><P><STRONG>SAP Fiori elements extension: upload Excel files to create new entries using building blocks</STRONG></P><P>This post guides you through the process of implementing an SAP Fiori elements application by leveraging the newly released SAP Fiori elements field building block, which simplifies the implementation compared to the previous method.</P><P><A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-elements-extension-upload-excel-files-to-create-new-entries-using/ba-p/13943173" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-fiori-elements-extension-upload-excel-files-to-create-new-entries-using/ba-p/13943173</A></P><P><STRONG>Joule to migrate SAPUI5 apps to TypeScript</STRONG></P><P>As you probably know,&nbsp;<A href="https://community.sap.com/t5/technology-blogs-by-sap/joule-for-freestyle-sapui5-development-in-sap-build-code/ba-p/13650005" target="_blank">Joule helps writing freestyle SAPUI5 code</A>&nbsp;in SAP Build Code.&nbsp;Joule's&nbsp;latest feature offers&nbsp;an&nbsp;AI-driven&nbsp;migration of UI5 applications to TypeScript, which, compared to JavaScript, enables&nbsp;an improved development efficiency.&nbsp;See the details in&nbsp;<A href="https://community.sap.com/t5/technology-blogs-by-sap/sapui5-meets-typescript-a-smooth-migration-journey-with-joule/ba-p/13958872" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sapui5-meets-typescript-a-smooth-migration-journey-with-joule/ba-p/13958872</A></P><P><STRONG>Building SAPUI5 Apps for SAP Build Work Zone</STRONG></P><P>This new guide&nbsp;gives a lot of technical insights into SAPUI5 apps running on SAP BTP:&nbsp;You will learn how to structure complex SAPUI5 applications to avoid common pitfalls, how multiple apps work with a shared reuse library and how to&nbsp;integrate business solutions as content providers into SAP Build Work Zone.&nbsp;<BR /><A href="https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-1/ba-p/13923459" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/designing-ui5-apps-as-business-solution-for-sap-build-work-zone-part-1/ba-p/13923459​</A></P><P><STRONG>SAPUI5 flexibility to adapt standard SAP apps </STRONG></P><P>SAPUI5 flexibility provides features to align with a clean core approach with on-stack extensions. SAP standard apps remain untouched, no modifications are needed, and even predefined extension points are unnecessary.&nbsp;<BR /><A href="https://community.sap.com/t5/technology-blogs-by-sap/extending-sapui5-apps-adaptation-projects-vs-extension-projects/ba-p/13961264" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/extending-sapui5-apps-adaptation-projects-vs-extension-projects/ba-p/13961264</A></P><P><STRONG>AI is NOT invited to our meetings </STRONG></P><P>In our monthly SAP development roundtable several people have been recording our calls and generating AI summaries. We have received some complaints. Going forward, we ask that you don’t do this. Our goal is for everyone to share openly. Having a recording and/or transcript might prevent this. If we demo something new and exciting, we’ll create a recording to share. Otherwise, please do not invite your AI or chatbot to join. People only!</P><P><STRONG>SAP S/4HANA extensibility: A holistic summary </STRONG></P><P>This series of articles is a holistic summary of extensibility with SAP S/4HANA. It captures the challenges and shows the essence of what we do at SAP, together with partners and customers (beyond providing the business solutions of course).</P><P><A href="https://community.sap.com/t5/technology-blogs-by-members/why-s-4hana-extensibility-options-are-crucial/ba-p/13921038" target="_blank">https://community.sap.com/t5/technology-blogs-by-members/why-s-4hana-extensibility-options-are-crucial/ba-p/13921038</A></P><P><STRONG>SAP Build Code updates </STRONG></P><P>Read about the latest updates to SAP Build Code. There are enhancements for experts, beginners, and everyone in between.</P><P><A href="https://community.sap.com/t5/technology-blogs-by-sap/product-updates-for-sap-build-code-november-2024-edition/ba-p/13948533" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/product-updates-for-sap-build-code-november-2024-edition/ba-p/13948533</A></P><P><STRONG>Behind the curtain on our development processes </STRONG></P><P>SAP UX Engineering is moving from traditional scrum/agile to a product-oriented model. This will redefine how we deliver value. Scrum has brought structure and efficiency, but we are now bringing together teams comprised of Product Management, Engineering, and Design. This will all us to focus on what matters most: customer outcomes over feature output or velocity. Read the first post of the 4-part series</P><P><A href="https://www.linkedin.com/pulse/why-ux-engineering-changing-sebastian-steinhauer-pkofe/" target="_blank" rel="noopener nofollow noreferrer">https://www.linkedin.com/pulse/why-ux-engineering-changing-sebastian-steinhauer-pkofe/</A></P><P><STRONG>Events</STRONG></P><P><STRONG>SAP Fiori Innovation Day Silicon Valley on Feb 5 </STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PeterSpielvogel_1-1736800681818.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/211528i7BA7753650F8711A/image-size/large?v=v2&amp;px=999" role="button" title="PeterSpielvogel_1-1736800681818.png" alt="PeterSpielvogel_1-1736800681818.png" /></span></P><P>&nbsp;</P><P>New innovations make the user experience for SAP S/4HANA intuitive, modern, and highly configurable. People have the information they need at their fingertips and can collaborate with colleagues to make better decisions. It’s easier than ever to adapt apps to meet your needs or to create new ones using our powerful and easy-to-use tools.</P><P>In this full-day workshop, we will cover:</P><UL><LI>SAP’s UX strategy and how it is evolving to fulfill the promise of the intelligent, collaborative enterprise</LI><LI>Extending SAP S/4HANA while keeping a clean core</LI><LI>Building apps using the latest tools and technologies – the same ones SAP uses to build apps for SAP S/4HANA, including a hands-on session</LI><LI>How to move your organization forward, including how to take advantage of AI for developing applications</LI></UL><P>Register now:<BR /><A href="https://events.sap.com/noam/sap-fiori-innovation-day-silicon-valley/en/home" target="_blank" rel="noopener noreferrer">https://events.sap.com/noam/sap-fiori-innovation-day-silicon-valley/en/home</A></P><P>&nbsp;</P><P><STRONG>If you can't make it to Palo Alto, where should we have our next SAP Fiori Innovation Day? </STRONG></P><P>We are planning our 2025 SAP Fiori Innovation Day schedule. Please let us know in which location you might be interested in joining us.</P><P>We will not have events in every location, but we want to get a sense of where you are willing to travel to learn about SAP Fiori app development (see topics above).</P><P><A href="https://events.sap.com/sap-fiori-innovation-day-2025/en/home" target="_blank" rel="noopener noreferrer">https://events.sap.com/sap-fiori-innovation-day-2025/en/home</A></P><P>&nbsp;</P><P><STRONG>SAP Fiori Innovation Day Heidelberg recap </STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PeterSpielvogel_2-1736800681846.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/211529i3AD0C30206FDAC5E/image-size/large?v=v2&amp;px=999" role="button" title="PeterSpielvogel_2-1736800681846.png" alt="PeterSpielvogel_2-1736800681846.png" /></span></P><P>&nbsp;</P><P>SAP Fiori Innovation Day in Heidelberg was a full day of learning, networking, and fun. Read about what you missed. Hope you can join us next time.</P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-innovation-day-in-heidelberg-focused-on-using-ai-to-make-apps/ba-p/13949089" target="_blank">https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-innovation-day-in-heidelberg-focused-on-using-ai-to-make-apps/ba-p/13949089</A></P><P>&nbsp;</P><P><STRONG>ASUG Annual Conference call for papers is now open </STRONG></P><P>SAP Sapphire is scheduled for May 19-21, 2025. If you want to speak at the ASUG Annual Conference, their call for papers is open until February 14. Details on their site:</P><P><A href="https://www.cvent.com/c/abstracts/71738f29-f5f6-4b3d-9738-ae643a743457" target="_blank" rel="noopener nofollow noreferrer">https://www.cvent.com/c/abstracts/71738f29-f5f6-4b3d-9738-ae643a743457</A></P><P>&nbsp;</P><P><STRONG>Back issues from the past year</STRONG></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-november-2024-issue-31/ba-p/13929385" target="_blank">SAP Fiori development newsletter November 2024 (issue #31)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-september-2024-issue-30/ba-p/13870115" target="_blank">SAP Fiori development newsletter September 2024 (issue #30)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-july-2024-issue-29/ba-p/13762548" target="_blank">SAP Fiori development newsletter July 2024 (issue #29)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-may-2024-issue-28/ba-p/13702765" target="_blank">SAP FIori development newsletter May 2024 (issue #28)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-march-2024-issue-27/ba-p/13646140" target="_blank">SAP Fiori development newsletter March 2024 (issue #27)</A></P><P><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-fiori-development-newsletter-january-2024-issue-26/ba-p/13582916" target="_blank">SAP Fiori development newsletter January 2024 (issue #26)</A></P><P>&nbsp;</P> 2025-01-13T21:39:55.968000+01:00 https://community.sap.com/t5/technology-blogs-by-members/3-3-from-javascript-to-typescript-the-shocking-results-of-our-sapui5/ba-p/13984355 3/3 From JavaScript to TypeScript: The Shocking Results of Our SAPUI5 Transformation 2025-01-14T16:25:23.164000+01:00 PetrBecka https://community.sap.com/t5/user/viewprofilepage/user-id/152296 <P>In the first two parts of this series, we explored <A href="https://community.sap.com/t5/technology-blogs-by-members/1-3-from-javascript-to-typescript-how-we-enhanced-code-reliability-in/ba-p/13878726" target="_self">why we transitioned to TypeScript</A> and <A href="https://community.sap.com/t5/technology-blogs-by-members/2-3-from-javascript-to-typescript-how-we-enhanced-code-reliability-in/ba-p/13925918" target="_self">how we structured the adoption process</A> for our SAPUI5 applications. Now, in this final part, we’ll evaluate the results of this shift and discuss how TypeScript has fundamentally transformed not only the quality of our applications but also the efficiency and productivity of our development team.</P><P>&nbsp;</P><H3 id="toc-hId-1208477919">What TypeScript Has Brought to Our Development Process</H3><P>The transition to TypeScript has proven to be a game changer, delivering improvements on multiple fronts. Let’s break down the key areas where we’ve seen tangible benefits:</P><H4 id="toc-hId-1141047133">1. <STRONG>Dramatic Reduction in Bugs</STRONG></H4><P>With TypeScript’s static typing and robust type checking, we’ve eliminated 35–45% of errors in our applications. These were primarily the kinds of technical bugs that often led to runtime crashes, frozen interfaces, or non-functional features. Now, the vast majority of reported issues pertain to business logic, such as missing inputs or incomplete processes, rather than underlying technical faults.</P><P>This shift allows us to focus our efforts on collaborating with clients to refine their workflows rather than troubleshooting application failures.</P><H4 id="toc-hId-944533628">2. <STRONG>Increased Team Efficiency</STRONG></H4><P>One of the most immediate and measurable impacts of adopting TypeScript has been the boost in our team’s efficiency. Here’s why:</P><UL><LI><P><STRONG>Autocomplete and IntelliSense:</STRONG> Developers now benefit from features like autocomplete, which provide instant suggestions for available properties, methods, and data types. This not only reduces the time spent referencing documentation but also ensures that the code being written is accurate and complete.</P></LI></UL><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-javascript"><code>const user: User = { id: 1, name: "John Doe", email: "john.doe@example.com", }; // Autocomplete helps ensure property names and methods are correctly used: console.log(user.email); // Suggestions for 'id', 'name', 'email' appear instantly.</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><UL><LI><P><STRONG>Faster Development:</STRONG> With TypeScript guiding developers and preventing many errors at compile time, the need for extensive debugging is reduced. This means more time spent on new features and improvements, rather than firefighting bugs.</P></LI><LI><P><STRONG>Simplified Maintenance:</STRONG> TypeScript’s stricter structure makes the codebase more predictable and easier to navigate. As a result, maintaining and extending our applications has become far less time-consuming.</P></LI></UL><H4 id="toc-hId-748020123">3. <STRONG>Improved Application Architecture</STRONG></H4><P>TypeScript encourages a more thoughtful approach to designing applications. With tools like interfaces, enums, and generics, we can define clear data models and relationships, making our applications more robust and easier to extend in the future. For example:</P><UL><LI><STRONG>Better modularity:</STRONG> We’ve been able to break down applications into smaller, reusable modules.</LI><LI><STRONG>Scalability:</STRONG> The strong typing system ensures that as our applications grow, the structure remains sound and consistent.</LI></UL><P>&nbsp;</P><H3 id="toc-hId-422423899">Practices That Ensure Long-Term Success with TypeScript</H3><P>To maximize the benefits of TypeScript, we’ve implemented several key practices:</P><OL><LI><P><STRONG>Centralized Declarations:</STRONG> All type definitions, enums, and interfaces are stored in a single declarations file to maintain consistency and ensure changes propagate across the codebase.</P></LI><LI><P><STRONG>Avoid Overusing Type Assertions:</STRONG> We explicitly account for undefined or null values, preventing errors caused by assumptions about data availability.</P></LI><LI><P><STRONG>Ban on the any Type:</STRONG> Using any is strictly prohibited as it negates the advantages of static typing. Instead, we leverage generics and proper type definitions to ensure flexibility without compromising safety.</P></LI><LI><P><STRONG>Thoughtful Code Reviews:</STRONG> Our reviews now emphasize adherence to TypeScript’s principles, such as avoiding unnecessary complexity in type definitions or ensuring proper handling of edge cases.</P></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="OpenAI. (2025). A cartoon illustration of a software web developers avoiding any keyword in TypeScript [AI-generated image]. DALL-E" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/211561iC0008D2BE15DA836/image-size/large?v=v2&amp;px=999" role="button" title="ANY.jpg" alt="OpenAI. (2025). A cartoon illustration of a software web developers avoiding any keyword in TypeScript [AI-generated image]. DALL-E" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">OpenAI. (2025). A cartoon illustration of a software web developers avoiding any keyword in TypeScript [AI-generated image]. DALL-E</span></span><SPAN>&nbsp;</SPAN></P><H3 id="toc-hId-225910394">General Outcomes: A More Effective and Resilient Team</H3><P>The move to TypeScript has had a profound impact on how our team works. Here’s a summary of the key outcomes:</P><UL><LI><P><STRONG>Higher Productivity:</STRONG> By eliminating many common sources of bugs, our team spends significantly less time on reactive tasks like debugging and maintenance. This allows us to focus on proactive work, such as new feature development and optimizing business processes.</P></LI><LI><P><STRONG>Faster Development Cycles:</STRONG> Autocomplete and intelligent type checking accelerate coding, even if TypeScript’s syntax is occasionally more verbose. This faster pace has enabled us to deliver solutions more quickly and with greater confidence.</P></LI><LI><P><STRONG>Better Client Collaboration:</STRONG> With fewer technical issues to address, we can work more closely with clients on refining their requirements and ensuring our applications align with their business goals. This has strengthened relationships and opened doors to new opportunities.</P></LI><LI><P><STRONG>Future-Proof Applications:</STRONG> TypeScript has made our applications more robust and scalable. Its strong typing system ensures that as our solutions evolve, they remain easier to maintain and extend.</P></LI></UL><P>&nbsp;</P><H3 id="toc-hId-29396889">Conclusion: A Transformative Shift for SAPUI5 Development</H3><P>Transitioning to TypeScript has fundamentally transformed our approach to development. By reducing errors, improving productivity, and fostering a more resilient architecture, we’ve not only improved the quality of our applications but also elevated our team’s effectiveness.</P><P>This journey has shown us that adopting modern tools like TypeScript is more than just a technical upgrade—it’s an investment in the long-term success of our team and our solutions. The efficiency gains, combined with the trust and confidence we’ve built with our clients, have set the stage for continued growth and innovation.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="OpenAI. (2025). A cartoon illustration of a software web developer handing over application created in TypeScript technology [AI-generated image]. DALL-E" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/211562iF24140239E31DBA3/image-size/large?v=v2&amp;px=999" role="button" title="hadshake.jpg" alt="OpenAI. (2025). A cartoon illustration of a software web developer handing over application created in TypeScript technology [AI-generated image]. DALL-E" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">OpenAI. (2025). A cartoon illustration of a software web developer handing over application created in TypeScript technology [AI-generated image]. DALL-E</span></span></P><P>&nbsp;</P><H3 id="toc-hId--167116616">Join the Discussion</H3><P>Have you implemented TypeScript in your projects? How has it influenced your team’s workflow and application quality? Share your experiences in the comments — we’d love to hear your insights and ideas as we continue to learn and improve together. Let’s shape the future of SAPUI5 development as a community!</P><P>&nbsp;</P> 2025-01-14T16:25:23.164000+01:00 https://community.sap.com/t5/application-development-blog-posts/sap-developer-news-january-16th-2025/ba-p/13988216 SAP Developer News, January 16th, 2025 2025-01-16T21:10:00.023000+01:00 thomas_jung https://community.sap.com/t5/user/viewprofilepage/user-id/139 <P><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FBZdboT6EdZw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DBZdboT6EdZw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FBZdboT6EdZw%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="400" height="225" scrolling="no" title="SAP Developer News" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><STRONG>Podcast: </STRONG><A href="https://podcast.opensap.info/sap-developers/2025/01/16/sap-developer-news-january-16th-2025/" target="_blank" rel="nofollow noopener noreferrer">https://podcast.opensap.info/sap-developers/2025/01/16/sap-developer-news-january-16th-2025/</A></P><H3 id="toc-hId-1208595999">DESCRIPTION</H3><P><STRONG>Upload Files from Build Apps to DMS, DOX and Other Services</STRONG></P><UL><LI>Video #1: Set Up SAP Build Apps to Work with DMS – <A href="https://youtu.be/lhBB2mM9Nho" target="_blank" rel="nofollow noopener noreferrer">https://youtu.be/lhBB2mM9Nho</A></LI><LI>Video #2: Call DMS from SAP Build Apps – <A href="https://youtu.be/SJt_BzctwbI" target="_blank" rel="nofollow noopener noreferrer">https://youtu.be/SJt_BzctwbI</A></LI><LI>Video #3: Upload a File from Build Apps to DMS – <A href="https://youtu.be/gIW_tHOaNuY" target="_blank" rel="nofollow noopener noreferrer">https://youtu.be/gIW_tHOaNuY</A></LI><LI>Free DMS projects: <A href="https://github.com/sap-tutorials/sap-build-apps/tree/main/projects/dms" target="_blank" rel="nofollow noopener noreferrer">https://github.com/sap-tutorials/sap-build-apps/tree/main/projects/dms</A></LI><LI>Document Management Service Playlist: <A href="https://www.youtube.com/playlist?list=PL6RpkC85SLQCsKSvIOqMzFKW30B4TKXh-" target="_blank" rel="nofollow noopener noreferrer">https://www.youtube.com/playlist?list=PL6RpkC85SLQCsKSvIOqMzFKW30B4TKXh-</A></LI><LI>Ming Kho’s blog post on Build Apps and DMS: <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-management-service-dms/ba-p/13963628" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-management-service-dms/ba-p/13963628</A></LI><LI>Ming Kho’s blog post on Build Apps and DOX: <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-information-extraction-dox/ba-p/13964007" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-information-extraction-dox/ba-p/13964007</A></LI></UL><P><STRONG>CAP December 2024 Release</STRONG></P><UL><LI>Release notes <A href="https://cap.cloud.sap/docs/releases/dec24" target="_blank" rel="nofollow noopener noreferrer">https://cap.cloud.sap/docs/releases/dec24</A></LI></UL><P><STRONG>Joule ABAP Developer Capabilities Early Adopter Program</STRONG></P><UL><LI><A href="https://influence.sap.com/sap/ino/#/campaign/3822" target="_blank" rel="noopener noreferrer">https://influence.sap.com/sap/ino/#/campaign/3822</A></LI></UL><P><STRONG>How to implement "readonly : update" for draft instances</STRONG></P><UL><LI><A href="https://community.sap.com/t5/technology-blogs-by-sap/how-to-implement-quot-readonly-update-quot-for-draft-instances/ba-p/13981904" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/how-to-implement-quot-readonly-update-quot-for-draft-instances/ba-p/13981904</A></LI></UL><P><STRONG>SAP Fiori Innovation Day &amp; UI5 Road Map 2025</STRONG></P><UL><LI>SAP Fiori Innovation Day Silicon Valley: <A href="https://events.sap.com/noam/sap-fiori-innovation-day-silicon-valley/en/home" target="_blank" rel="noopener noreferrer">https://events.sap.com/noam/sap-fiori-innovation-day-silicon-valley/en/home</A></LI><LI>UI5 Road Map Explorer: <A href="https://roadmaps.sap.com/board?PRODUCT=73554900100800001361&amp;range=CURRENT-LAST#Q1%202025" target="_blank" rel="noopener noreferrer">https://roadmaps.sap.com/board?PRODUCT=73554900100800001361&amp;range=CURRENT-LAST#Q1%202025</A></LI></UL><H3 id="toc-hId-1012082494">CHAPTER TITLES</H3><P>0:00 Intro<BR />0:10 Upload Files from Build Apps to DMS, DOX and Other Services<BR />1:51 CAP December 2024 Releas<BR />5:06 Joule ABAP Developer Capabilities Early Adopter Program<BR />6:02 How to implement "readonly : update" for draft instances<BR />6:58 SAP Fiori Innovation Day &amp; UI5 Road Map 2025</P><H3 id="toc-hId-815568989">Transcription</H3><P><STRONG>[Intro]</STRONG> This is the SAP Developer News for January 16th, 2025.</P><P><STRONG>[Daniel]</STRONG> SAP Build Apps has just released a new flow function that lets you upload documents to the BTP Document Management Service, the document information extraction service, or any service that requires a binary upload. Minko, a developer at SAP Build Apps, created the HTTP Destination and request flow function, which takes a multi-part request body and lets you specify a destination, both of which enable you to upload to the services. He has written two blogs, one on using it with DMS and one on using it with DMS, but I want to point out that I've just released three short videos on how to use this flow function with build apps and DMS, and I want to point out that I've just released three short videos on how to use this flow I've released an entire application that lets you navigate through a DMS repo. So it will list all the documents in the root or any folder in the DMS repo, let you upload documents, let you create folders, and let you delete folders and documents. All you need to do is attach your destination to your DMS repo. And I want to point out that we also have a playlist dedicated just to the document management service. It has videos on setting up DMS, unrelated to SAP Build, as well as how to use it with process automation, and build apps. Links to all of that content are in the description.</P><P><STRONG>[DJ]</STRONG> While most of us were taking some time off over the holiday period recently, the CAP team has kept on working and put out another regular monthly release. December 24 of this. As usual, there are plenty of highlights, some of which I want to bring to your attention here. There are so many I've actually got a list and a read through. Got some notes. And this also sees CAP Node.js at 8.6 and CAP Java at 3.6. Okay, so what have we got? There are changes and improvements in the CDS language and compiler area, specifically For example, a completely rewritten CQN specification using TypeScript declaration files, which in turn brings about improved documentation and also some Intellisense operations that are also improved. There's a new beta feature where foreign key elements of managed associations can be explicitly annotated. Moving to the Node.js flavor of CAPs specifically, there are new compiler related life cycle events. They're also in beta. There are some enhancements to CDS Env. These enhancements relate to source formats and profile-specific endv files. And CDSQL has some enhancements. And these enhancements bring about a more robust operation in general and also some new functions for CQN object construction. In the OData arena, there are also some additions and improvements relating to the OData containment feature, and also a move to allow query option-based provision of function parameters, which some of you, I'm sure, will enjoy. In the Java flavor of CAP, there are some important changes in the area of NPM build plugin support, and also the new Calaisi plugin for the document management service is now open source. Last but not least, in the tools area, there are many enhancements to the CDS REPL. Some of you may have seen these enhancements sort of take shape over the course of the first six episodes of the art and science of CAP, a live stream series that we ran recently with the one and only Daniel Hutzl. So I'll put a link to that also in the description to this item, as well as the link to this December 2024. for Capphire release notes, but also for TypeScript developers out there, you can now just use CDS watch to start the server and it will automatically detect a TypeScript project and under the hood it will run CDSTSX for you. There's also more, even more, in this December 2024 release, but I'll leave it to you to go and check out the release notes in Capphire. Until then, see you online.</P><P><STRONG>[Rich]</STRONG> Hey friends, Rich Heilman here. I just wanted to stop in a bit and let you know about the Joule ABAP Developer Capabilities Early Adopter Program for Customers and Partners. That's right, do you want to check out the Bleeding Edge technology helping ABAP developers become more efficient developers? If so, then go to the Influence. site and register for the early adopters program. Registration started on January 15th and will end on February 15th the same day we plan to release to customers. So again, if you are ready to get your hands dirty with AI and using Joule within ADT to help you with ABAP development, then please sign up for this excellent opportunity to try it out, give us some feedback, and make the product better for all. Thanks to ABAP developers, and we'll see you. See you soon. Bye for now.</P><P><STRONG>[Sheena]</STRONG> You might have noticed that when a field is defined as Read Only for updates in a Draft-enabled application, it cannot be edited after an initial value is provided. Andre Fischer in his latest blog post explains how to achieve the editing of such fields in Draft using the dynamic feature control option. For this, just replace the statement read-only update with features instance in your behavior definition. Then in your behavior implementation method, verify whether an active instance of the entity already exists. If yes, the field will be made read only, however, if no active instance exists, the field will remain editable. Please note that this is applicable only when an object is being created as a draft and has not yet been persisted. Check out the details and sample code in the blog post link provided in the description.</P><P><STRONG>[Nico]</STRONG> Hi everyone and welcome to the SAP Developer News. We have some updates in the Fiori and U5 area that we want to put your attention to. First of all, the SAP Fiori Innovation Day happens on February 5th in Silicon Valley. Definitely check it out if you're in the area. AI is going to be a hot topic, there's going to be a partner session, hands -on sessions and an outlook from the Fiori team on what's to come in the future. Check out the link to register in the future. the description of this video. And also related to Fiori, more UI5. The 2025 Roadmap is out now. Go check it out. If you're interested in UI5, there's some interesting items on there, and go follow. All right, check it out. Hope you see you soon. Bye.</P> 2025-01-16T21:10:00.023000+01:00