├── .devcontainer ├── .devcontainer └── Dockerfile ├── .github └── CODEOWNERS ├── .gitignore ├── .reuse └── dep5 ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── LICENSES └── Apache-2.0.txt ├── README.md ├── _i18n └── messages.properties ├── app ├── appconfig │ └── fioriSandboxConfig.json └── profilePic │ ├── index.html │ └── profilePic │ ├── Component.js │ ├── controller │ ├── App.controller.js │ └── BaseController.js │ ├── manifest.json │ ├── model │ └── models.js │ └── view │ ├── App.view.xml │ └── BusyDialog.fragment.xml ├── express-server.js ├── images ├── bas_clone.png ├── bas_dev_space.png ├── bas_npm_install.png ├── bas_npm_run_dev.png ├── base_npm_run.png ├── boarder.png ├── clone.png ├── cs_create.png ├── cs_npm_install.png ├── cs_npm_run.png ├── cs_npm_run_dev.png ├── cs_ready.png ├── favicon.ico ├── node_v_check.png ├── npm_install.png ├── npm_run_dev.png ├── npm_start.png └── sap_18.png ├── index.js ├── package-lock.json ├── package.json ├── routes ├── frontend.js ├── index.js └── profilePic.js ├── server ├── express.js ├── expressSecurity.js ├── healthCheck.js └── overloadProtection.js ├── tsconfig.json └── utils ├── loader.js ├── svgRender.js └── texts.js /.devcontainer/.devcontainer: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.216.0/containers/javascript-node 3 | { 4 | "name": "SAP Community Activity Badges Contributor Devcontainer", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | // Update 'VARIANT' to pick a Node version: 12, 14, 16 8 | "args": { "VARIANT": "16" } 9 | }, 10 | 11 | // Set *default* container specific settings.json values on container create. 12 | "settings": {}, 13 | 14 | // Add the IDs of extensions you want installed when the container is created. 15 | "extensions": [ 16 | "dbaeumer.vscode-eslint", 17 | "hookyqr.beautify", 18 | "coenraads.bracket-pair-colorizer-2", 19 | "eamodio.gitlens", 20 | "yzhang.markdown-all-in-one", 21 | "fivepointseven.node-version", 22 | "bengreenier.vscode-node-readme", 23 | "christian-kohler.path-intellisense", 24 | "humao.rest-client", 25 | "pflannery.vscode-versionlens", 26 | "visualstudioexptteam.vscodeintellicode", 27 | "vscode-icons-team.vscode-icons", 28 | "dotjoshjohnson.xml" 29 | ], 30 | 31 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 32 | "forwardPorts": [ 4000 ], 33 | 34 | // Use 'postCreateCommand' to run commands after the container is created. 35 | // "postCreateCommand": "yarn install", 36 | 37 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 38 | "remoteUser": "node" 39 | } -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/blob/v0.216.0/containers/javascript-node/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Node.js version: 16, 14, 12 4 | ARG VARIANT="16-buster" 5 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} 6 | 7 | # Prepare for apt-based install of Cloud Foundry CLI by adding Cloud Foundry Foundation public key & package repository 8 | # (see https://docs.cloudfoundry.org/cf-cli/install-go-cli.html#pkg-linux). 9 | RUN wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - ; \ 10 | echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list 11 | 12 | # Install extra tools for BTP development & deployment. 13 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 14 | && apt-get -y install --no-install-recommends cf-cli 15 | 16 | # Install global node modules for SAP BTP development. 17 | RUN su node -c "npm install -g yo mbt typescript" -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @jung-thomas 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | /mta_archives 107 | 108 | /app/*.zip -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: [sap-community-code-challenge] 3 | Upstream-Contact: Thomas Jung 4 | Source: https://github.com/sap-samples/sap-community-code-challenge 5 | Disclaimer: The code in this project may include calls to APIs (“API Calls”) of 6 | SAP or third-party products or services developed outside of this project 7 | (“External Products”). 8 | “APIs” means application programming interfaces, as well as their respective 9 | specifications and implementing code that allows software to communicate with 10 | other software. 11 | API Calls to External Products are not licensed under the open source license 12 | that governs this project. The use of such API Calls and related External 13 | Products are subject to applicable additional agreements with the relevant 14 | provider of the External Products. In no event shall the open source license 15 | that governs this project grant any rights in or to any External Products,or 16 | alter, expand or supersede any terms of the applicable additional agreements. 17 | If you have a valid license agreement with SAP for the use of a particular SAP 18 | External Product, then you may make use of any API Calls included in this 19 | project’s code for that SAP External Product, subject to the terms of such 20 | license agreement. If you do not have a valid license agreement for the use of 21 | a particular SAP External Product, then you may only make use of any API Calls 22 | in this project for that SAP External Product for your internal, non-productive 23 | and non-commercial test and evaluation of such API Calls. Nothing herein grants 24 | you any rights to use or access any SAP External Product, or provide any third 25 | parties the right to use of access any SAP External Product, through API Calls. 26 | 27 | Files: * 28 | Copyright: 2022 SAP SE or an SAP affiliate company and sap-community-awareness-code-challenge contributors 29 | License: Apache-2.0 30 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "appconfig", 4 | "healthcheck", 5 | "SAPUI" 6 | ], 7 | "SAP HANA Database Explorer.displaySapWebAnalyticsStartupNotification": false 8 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) 6 | 7 | ## [Unreleased] 8 | 9 | ## [1.0.0] - 2022-02-01 10 | 11 | ### Added 12 | 13 | - Initial release 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2022 SAP SE 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Not Maintained](https://img.shields.io/badge/Maintenance%20Level-Not%20Maintained-yellow.svg)](https://gist.github.com/cheerfulstoic/d107229326a01ff0f333a1d3476e068d) 2 | 3 | # SAP Community Code Challenge 4 | 5 | [![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/sap-community-code-challenge)](https://api.reuse.software/info/github.com/SAP-samples/sap-community-code-challenge) 6 | 7 | 8 | [![Visits Badge](https://badges.pufler.dev/visits/SAP-samples/sap-community-code-challenge)](https://badges.pufler.dev) 9 | [![Updated Badge](https://badges.pufler.dev/updated/SAP-samples/sap-community-code-challenge)](https://badges.pufler.dev) 10 | [![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/SAP-samples/sap-community-code-challenge) 11 | 12 | [![Contributors Display](https://badges.pufler.dev/contributors/SAP-samples/sap-community-code-challenge?size=50&padding=5&bots=false)](https://badges.pufler.dev) 13 | 14 | The [change log](https://github.com/SAP-samples/sap-community-code-challenge/blob/main/CHANGELOG.md) describes notable changes in this package. 15 | 16 | ## Description 17 | 18 | SAP Community Code Challenge: This repository is a template project/solution showing how to enhance your SAP Community profile picture with a new border. 19 | 20 | Some of the technology contained within this project: 21 | 22 | * [Node.js](https://nodejs.org/en/about/) 23 | * [SAPUI5 Image Editor Control](https://sapui5.hana.ondemand.com/#/entity/sap.suite.ui.commons.imageeditor) 24 | * [Sharp - High performance Node.js image processing](https://github.com/lovell/sharp) 25 | * [SVG Scalable Vector Graphics](https://developer.mozilla.org/en-US/docs/Web/SVG) 26 | 27 | ## Challenges 28 | 29 | Although this project is a complete code sample, it's really only intended to be the starting point. It's part of a code challenge; which means have some fun and learn at the same time. For the full details on the Code Challenge please see this [SAP Community Discussion Thread](https://groups.community.sap.com/t5/coffee-corner/gh-p/Coffee-Corner). But let's detail right here some of the possible challenges you might undertake using this starting point. 30 | 31 | The whole project can run locally. It's a [SAPUI5 app](/profilePic/#profilepic-ui) where you start by uploading the base picture you want. You can do some editing on it. Then you set it to a circular crop (since that's is what the SAP Community profile pic requires). When you press enhance picture it's uploaded to the "server" there we apply the border. Then you can save the final file (or edit if further if you want). Upon save it automatically opens your SAP Community Profile in another browser tab. There you can upload your newly enhanced profile picture. Now that you understand what the code sample does; here are the challenges. 32 | 33 | ### Run the Project Locally 34 | 35 | 1. Ensure that you have [Node.js](https://nodejs.org/en/about/) ver 12, 14 or 16 installed locally. 36 | ![Node Version Check](images/node_v_check.png) 37 | 38 | 2. [Clone this repository](https://github.com/SAP-samples/sap-community-code-challenge.git) 39 | ![Clone from GitHub](images/clone.png) 40 | 41 | 3. From the root of the project in a terminal issue the command `npm install`. This will install all project dependencies into the /node_modules folder. 42 | ![npm install](images/npm_install.png) 43 | 44 | 4. Once all dependencies are installed, issue the command `npm start` from the terminal. This will start a local web server. You can test the application locally via the url: [http://localhost:4000/profilepic/](http://localhost:4000/profilepic/) 45 | ![npm start](images/npm_start.png) 46 | 47 | 5. [Optional]: If you plan to make changes to the project code, there is a command `npm run dev` that you can use for testing. This command will automatically restart the server with each code change you make. This can be quite convenient when making frequent changes and constantly retesting. 48 | ![npm run dev](images/npm_run_dev.png) 49 | 50 | ### Run the Project on the SAP Business Application Studio 51 | 52 | 1. Create or reuse an SAP Business Application Studio Dev Space of type "Full Stack Cloud Development". This will ensure that you have the correct Node.js runtime already installed into the development environment. 53 | ![Business Application Studio Dev Space](images/bas_dev_space.png) 54 | 55 | 2. Clone [this repository](https://github.com/SAP-samples/sap-community-code-challenge.git) into the workspace. 56 | ![Clone into Workspace](images/bas_clone.png) 57 | 58 | 3. From the root of the project in a terminal issue the command `npm install`. This will install all project dependencies into the /node_modules folder. 59 | ![npm install](images/bas_npm_install.png) 60 | 61 | 4. Once all dependencies are installed, issue the command `npm start` from the terminal. This will start a local web server. You can test the application locally by using the "Expose and Open" button 62 | ![npm start](images/base_npm_run.png) 63 | 64 | 5. [Optional]: If you plan to make changes to the project code, there is a command `npm run dev` that you can use for testing. This command will automatically restart the server with each code change you make. This can be quite convenient when making frequent changes and constantly retesting. 65 | ![npm run dev](images/bas_npm_run_dev.png) 66 | 67 | ### Run the Project in a Dev Container or Codespaces 68 | 69 | 1. From GitHub choose the option to create a new codespace. 70 | ![Create codespace](images/cs_create.png) 71 | 72 | 2. You can then use this codespace from the browser or open it remotely in your locally VSCode installation. The codespace will be pre-configured with the correct Node.js runtime and already has the project cloned into it. 73 | ![Clone into Workspace](images/cs_ready.png) 74 | 75 | 3. From the root of the project in a terminal issue the command `npm install`. This will install all project dependencies into the /node_modules folder. 76 | ![npm install](images/cs_npm_install.png) 77 | 78 | 4. Once all dependencies are installed, issue the command `npm start` from the terminal. This will start a local web server. You can test the application locally by using the "Open in Browser" button 79 | ![npm start](images/cs_npm_run.png) 80 | 81 | 5. [Optional]: If you plan to make changes to the project code, there is a command `npm run dev` that you can use for testing. This command will automatically restart the server with each code change you make. This can be quite convenient when making frequent changes and constantly retesting. 82 | ![npm run dev](images/cs_npm_run_dev.png) 83 | 84 | ### Learn about SVG - Change the Enhancement 85 | 86 | Create your own profile enhancement. Maybe instead of a border it adds your profile name, badges, etc. 87 | 88 | ### Port the Whole Project to Another Programming Language 89 | 90 | Try and port the whole project to another programming language. I'm sure we will let lots of people converting it to ABAP. 91 | 92 | ### Multiple Image Enhancement Options in the UI 93 | 94 | Extend the app to offer multiple server side enhancements but then extend the SAPUI5 frontend to allow the end user to choose the enhancement type. The trick there is sending the choice along with the upload (it can be done but its tricky). That challenge would be focused on UI5 skills. 95 | 96 | ## Requirements 97 | 98 | Node.js version 12.x, 14.x, or 16.x [https://nodejs.org/en/download/](https://nodejs.org/en/download/) 99 | 100 | ## Download and Installation 101 | 102 | See [Challenges](#challenges) 103 | 104 | ## Known Issues 105 | 106 | None 107 | 108 | ## How to obtain support 109 | 110 | [Create an issue](https://github.com/SAP-samples/sap-community-awareness-code-challenge/issues) in this repository if you find a bug or have questions about the content. 111 | 112 | For additional support, [ask a question in SAP Community](https://answers.sap.com/questions/ask.html). 113 | 114 | ## Contributing 115 | 116 | If you wish to contribute code, offer fixes or improvements, please send a pull request. Due to legal reasons, contributors will be asked to accept a DCO when they create the first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/). 117 | 118 | ## License 119 | 120 | Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](https://github.com/SAP-samples/sap-community-code-challenge/blob/main/LICENSES/Apache-2.0.txt) file. 121 | -------------------------------------------------------------------------------- /_i18n/messages.properties: -------------------------------------------------------------------------------- 1 | errPort=is not a valid HTTP port value 2 | lagError=Event Loop Lag Exceeded: {0} milliseconds 3 | errFileType=Invalid file type. Only jpg, png and gif image files are allowed. 4 | errFileTooLarge=Uploaded file is too large. Please choose a file less than 20MB in size 5 | appTitle=SAP Community Profile Picture Editor 6 | appDescription=SAP Community Profile Picture Editor / Enhancer 7 | Toolbar1=Choose Selfie Template 8 | Toolbar2=Choose Your Picture and Upload 9 | Toolbar3=Edit and Download Final Image 10 | Upload=Enhance Your Picture 11 | placeholder=Choose File for Upload... 12 | gui.loading=Processing Picture 13 | gui.loadingLong=Please wait ...Processing Picture -------------------------------------------------------------------------------- /app/appconfig/fioriSandboxConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultRenderer": "fiori2", 3 | "bootstrapPlugins": { 4 | "RuntimeAuthoringPlugin": { 5 | "component": "sap.ushell.plugins.rta" 6 | }, 7 | "PersonalizePlugin": { 8 | "component": "sap.ushell.plugins.rta-personalize" 9 | } 10 | }, 11 | "services": { 12 | "NavTargetResolution": { 13 | "config": { 14 | "allowTestUrlComponentConfig": true, 15 | "enableClientSideTargetResolution": true 16 | } 17 | }, 18 | "EndUserFeedback": { 19 | "adapter": { 20 | "config": { 21 | "enabled": true 22 | } 23 | } 24 | } 25 | }, 26 | "applications": { 27 | "profilepic-ui": { 28 | "title": "", 29 | "description": "", 30 | "additionalInformation": "SAPUI5.Component=sap.profilePic", 31 | "applicationType": "URL", 32 | "url": "./profilePic", 33 | "navigationMode": "embedded" 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /app/profilePic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 21 | 22 | 25 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/profilePic/profilePic/Component.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /*eslint-env es6 */ 3 | sap.ui.define([ 4 | "sap/ui/core/UIComponent", 5 | "sap/profilePic/model/models" 6 | ], function (UIComponent, models) { 7 | "use strict" 8 | 9 | return UIComponent.extend("profilePic.Component", { 10 | 11 | metadata: { 12 | manifest: "json" 13 | }, 14 | 15 | init: function () { 16 | // call the base component's init function 17 | UIComponent.prototype.init.apply(this, arguments) 18 | 19 | // enable routing 20 | this.getRouter().initialize() 21 | 22 | // set the device model 23 | this.setModel(models.createDeviceModel(), "device") 24 | } 25 | 26 | 27 | }) 28 | }) -------------------------------------------------------------------------------- /app/profilePic/profilePic/controller/App.controller.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /*eslint-env es6 */ 3 | "use strict"; 4 | sap.ui.define([ 5 | "profilePic/controller/BaseController", 6 | "sap/m/MessageToast", 7 | "sap/ui/core/Core", 8 | "sap/ui/model/json/JSONModel", 9 | "sap/ui/Device", 10 | "sap/suite/ui/commons/library" 11 | ], 12 | function (BaseController, MessageToast, oCore, JSONModel, Device, SuiteLibrary) { 13 | 14 | return BaseController.extend("profilePic.controller.App", { 15 | onInit: function () { 16 | var oImageEditor = this.getView().byId("image"), 17 | oModel = new JSONModel({ 18 | blocked: true 19 | }) 20 | 21 | this.getView().setModel(oModel) 22 | if (!Device.browser.msie) { 23 | // svg files are not supported in Internet Explorer 24 | oImageEditor.setCustomShapeSrc(sap.ui.require.toUrl("sap/suite/ui/commons/statusindicator") + "/shapes/bulb.svg") 25 | } 26 | }, 27 | 28 | uploadPressed: async function (oEvent) { 29 | let view = this.getView() 30 | let controller = view.getController() 31 | let oFileUploader = view.byId("fileToUpload") 32 | if (!oFileUploader.getValue()) { 33 | MessageToast.show("Choose a file first") 34 | return 35 | } 36 | let param = view.byId("uploadParam") 37 | //param.setValue(oInput.getActivePage()) 38 | oFileUploader.getParameters() 39 | var oImageEditor = this.getView().byId("image") 40 | oImageEditor.applyVisibleCrop() 41 | console.log(oImageEditor.getMode()) 42 | oFileUploader.getProcessedBlobsFromArray = async function (oBlobs) { 43 | return new Promise(async (resolve, reject) => { 44 | let newBlob = await oImageEditor.getImageAsBlob() 45 | resolve([newBlob]) 46 | }) 47 | } 48 | controller.startBusy() 49 | oFileUploader.upload(true) 50 | }, 51 | 52 | uploadStart: async function (oEvent) { 53 | let view = this.getView() 54 | let controller = view.getController() 55 | controller.startBusy() 56 | }, 57 | 58 | uploadComplete: async function (oEvent) { 59 | let view = this.getView() 60 | let controller = view.getController() 61 | let dataURL = "data:image/png;base64," + oEvent.getParameters().responseRaw 62 | let oImageEditor = view.byId("image") 63 | await oImageEditor.setSrc(dataURL) 64 | controller.endBusy(controller) 65 | }, 66 | 67 | onSaveAsPress: async function () { 68 | let view = this.getView() 69 | let controller = view.getController() 70 | let oImageEditor = view.byId("image") 71 | oImageEditor.openSaveDialog() 72 | controller.openUrl('https://people.sap.com/', true) 73 | 74 | }, 75 | onImageLoaded: async function (oEvent) { 76 | let view = this.getView() 77 | let oImageEditor = view.byId("image") 78 | oImageEditor.zoomToFit() 79 | oImageEditor.setCropAreaByRatio(1, 1) 80 | oImageEditor.setMode(SuiteLibrary.ImageEditorMode.CropEllipse) 81 | console.log(oImageEditor.getMode()) 82 | 83 | 84 | 85 | }, 86 | onFileChange: async function (oEvent) { 87 | var oFile = oEvent.getParameter("files")[0], 88 | oImageEditor = this.getView().byId("image") 89 | if (!oFile) { 90 | return 91 | } 92 | this.getView().getModel().setProperty("/blocked", true) 93 | await oImageEditor.setSrc(oFile) 94 | 95 | } 96 | }) 97 | } 98 | ) -------------------------------------------------------------------------------- /app/profilePic/profilePic/controller/BaseController.js: -------------------------------------------------------------------------------- 1 | /*global history */ 2 | /* eslint-disable no-undef */ 3 | sap.ui.define([ 4 | "sap/ui/core/mvc/Controller", 5 | "sap/ui/core/routing/History", 6 | "sap/ui/core/Fragment", 7 | "sap/ui/core/syncStyleClass", 8 | ], function (Controller, History, Fragment, syncStyleClass) { 9 | "use strict"; 10 | 11 | return Controller.extend("profilePic.controller.BaseController", { 12 | /** 13 | * Convenience method for accessing the router in every controller of the application. 14 | * @public 15 | * @returns {sap.ui.core.routing.Router} the router for this component 16 | */ 17 | getRouter: function () { 18 | return this.getOwnerComponent().getRouter(); 19 | }, 20 | 21 | /** 22 | * Convenience method for getting the view model by name in every controller of the application. 23 | * @public 24 | * @param {string} sName the model name 25 | * @returns {sap.ui.model.Model} the model instance 26 | */ 27 | getModel: function (sName) { 28 | return this.getView().getModel(sName); 29 | }, 30 | 31 | /** 32 | * Convenience method for setting the view model in every controller of the application. 33 | * @public 34 | * @param {sap.ui.model.Model} oModel the model instance 35 | * @param {string} sName the model name 36 | * @returns {sap.ui.mvc.View} the view instance 37 | */ 38 | setModel: function (oModel, sName) { 39 | return this.getView().setModel(oModel, sName); 40 | }, 41 | 42 | /** 43 | * Convenience method for getting the resource bundle. 44 | * @public 45 | * @returns {sap.ui.model.resource.ResourceModel} the resourceModel of the component 46 | */ 47 | getResourceBundle: function () { 48 | return this.getOwnerComponent().getModel("i18n").getResourceBundle(); 49 | }, 50 | 51 | /** 52 | * Event handler for navigating back. 53 | * It there is a history entry we go one step back in the browser history 54 | * If not, it will replace the current entry of the browser history with the master route. 55 | * @public 56 | */ 57 | onNavBack: function () { 58 | var sPreviousHash = History.getInstance().getPreviousHash(); 59 | 60 | if (sPreviousHash !== undefined) { 61 | history.go(-1); 62 | } else { 63 | this.getRouter().navTo("master", {}, true) 64 | } 65 | }, 66 | 67 | 68 | openUrl: function (url, newTab) { 69 | // Require the URLHelper and open the URL in a new window or tab (same as _blank): 70 | sap.ui.require(["sap/m/library"], ({ URLHelper }) => URLHelper.redirect(url, newTab)); 71 | }, 72 | 73 | 74 | startBusy: function () { 75 | if (!this._pBusyDialog) { 76 | this._pBusyDialog = Fragment.load({ 77 | name: "profilePic.view.BusyDialog", 78 | controller: this 79 | }).then(function (oBusyDialog) { 80 | this.getView().addDependent(oBusyDialog) 81 | syncStyleClass("sapUiSizeCompact", this.getView(), oBusyDialog) 82 | return oBusyDialog 83 | }.bind(this)) 84 | } 85 | 86 | this._pBusyDialog.then(function (oBusyDialog) { 87 | oBusyDialog.open() 88 | }.bind(this)) 89 | }, 90 | endBusy: function (oController) { 91 | if (oController._pBusyDialog) { 92 | oController._pBusyDialog.then(function (oBusyDialog) { 93 | oBusyDialog.close() 94 | }) 95 | } 96 | }, 97 | 98 | onErrorCall: function (oError, oController) { 99 | if (oController) { 100 | oController.endBusy(oController) 101 | } 102 | sap.ui.require(["sap/m/MessageBox"], (MessageBox) => { 103 | console.log(oError) 104 | if (oError.statusCode === 500 || oError.statusCode === 400 || oError.statusCode === "500" || oError.statusCode === "400" || oError.status === 500) { 105 | var errorRes = oError.responseText 106 | MessageBox.alert(errorRes) 107 | return 108 | } else { 109 | MessageBox.alert(oError.statusText) 110 | return 111 | } 112 | }) 113 | } 114 | 115 | }) 116 | 117 | } 118 | ) -------------------------------------------------------------------------------- /app/profilePic/profilePic/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "_version": "1.33.0", 3 | "sap.app": { 4 | "id": "profilePic", 5 | "type": "application", 6 | "i18n": "/i18n/messages.properties", 7 | "applicationVersion": { 8 | "version": "1.0.0" 9 | }, 10 | "title": "{{appTitle}}", 11 | "description": "{{appDescription}}", 12 | "sourceTemplate": { 13 | "id": "html5moduletemplates.basicSAPUI5ApplicationProjectModule", 14 | "version": "1.40.12" 15 | } 16 | }, 17 | 18 | "sap.ui": { 19 | "technology": "UI5", 20 | "icons": { 21 | "icon": "/favicon.ico", 22 | "favIcon": "/favicon.ico", 23 | "phone": "", 24 | "phone@2": "", 25 | "tablet": "", 26 | "tablet@2": "" 27 | }, 28 | "deviceTypes": { 29 | "desktop": true, 30 | "tablet": true, 31 | "phone": true 32 | } 33 | }, 34 | 35 | "sap.ui5": { 36 | "flexEnabled": false, 37 | "rootView": { 38 | "viewName": "profilePic.view.App", 39 | "type": "XML", 40 | "async": true, 41 | "id": "App" 42 | }, 43 | "dependencies": { 44 | "minUI5Version": "1.98.0", 45 | "libs": { 46 | "sap.ui.core": {}, 47 | "sap.m": {}, 48 | "sap.ui.layout": {} 49 | } 50 | }, 51 | "contentDensities": { 52 | "compact": true, 53 | "cozy": true 54 | }, 55 | "models": { 56 | "config": { 57 | "type": "sap.ui.model.json.JSONModel" 58 | }, 59 | "i18n": { 60 | "type": "sap.ui.model.resource.ResourceModel", 61 | "settings": { 62 | "bundleUrl": "/i18n/messages.properties" 63 | } 64 | } 65 | }, 66 | "resources": { 67 | "css": [{ 68 | "uri": "../css/style.css" 69 | }] 70 | }, 71 | "routing": { 72 | "config": { 73 | "routerClass": "sap.m.routing.Router", 74 | "viewType": "XML", 75 | "async": true, 76 | "viewPath": "profilePic.view", 77 | "controlAggregation": "pages", 78 | "controlId": "app", 79 | "clearControlAggregation": false 80 | }, 81 | "routes": [{ 82 | "name": "RouteApp", 83 | "pattern": "RouteApp", 84 | "target": ["TargetApp"] 85 | }], 86 | "targets": { 87 | "TargetApp": { 88 | "viewType": "XML", 89 | "transition": "slide", 90 | "clearControlAggregation": false, 91 | "viewId": "App", 92 | "viewName": "App" 93 | } 94 | } 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /app/profilePic/profilePic/model/models.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /*eslint-env es6 */ 3 | sap.ui.define([ 4 | "sap/ui/model/json/JSONModel", 5 | "sap/ui/Device" 6 | ], (JSONModel, Device) => { 7 | "use strict" 8 | 9 | return { 10 | 11 | createDeviceModel: () => { 12 | var oModel = new JSONModel(Device) 13 | oModel.setDefaultBindingMode("OneWay") 14 | return oModel 15 | } 16 | 17 | } 18 | }) -------------------------------------------------------------------------------- /app/profilePic/profilePic/view/App.view.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |