├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSE-SUMMARY ├── NOTICE ├── README.md ├── THIRD_PARTY_LICENSES ├── amplify.yml ├── app ├── App.css ├── components │ ├── Breadcrumbs.js │ ├── Cards.js │ ├── Labels.js │ ├── Navigation.js │ ├── constants.js │ └── utils.js ├── containers │ └── LandingPage.js ├── layout.js ├── page.js └── routers │ └── AppRouter.js ├── next.config.js ├── package-lock.json ├── package.json └── public ├── apple-touch-icon.png ├── atlas.csv ├── favicon.ico ├── image.png ├── index.html ├── manifest.json ├── rectangle_grey.png └── robots.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | 132 | # Mac 133 | .env 134 | .DS_Store 135 | 136 | # next.js 137 | /.next/ 138 | /out/ 139 | 140 | # production 141 | /build 142 | 143 | # misc 144 | *.pem 145 | 146 | # local env files 147 | .env*.local 148 | 149 | # vercel 150 | .vercel 151 | 152 | # typescript 153 | next-env.d.ts -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /LICENSE-SUMMARY: -------------------------------------------------------------------------------- 1 | This project is licensed under the terms of the Apache 2.0 license. See LICENSE. 2 | Included AWS Lambda functions are licensed under the MIT-0 license. See LICENSE-LAMBDA. 3 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Generative AI Atlas 2 | 3 | [:point_right: **Click here to access the _Generative AI Atlas_** :point_left:](https://gen-ai-atlas.d2fpo0i5kstaiq.amplifyapp.com) 4 | 5 | The **Generative AI Atlas** is an organized repository designed for individuals seeking to explore the newest content released by AWS on Generative AI. The Atlas serves as a publicly accessible directory that gathers various resources related to Generative AI, including Blog Posts, Code Samples, Tutorials, Videos, and Workshops, all published on official AWS channels. To facilitate a seamless exploration experience, the Atlas offers a search bar and a comprehensive set of filters, empowering users to quickly find relevant assets for a specific use case of interest. Whether you’re a beginner or an experienced practitioner, the Generative AI Atlas presents a curated selection of content to support your journey. 6 | 7 | ![Generative AI Atlas](public/image.png) 8 | 9 | 10 | ### Generative AI Atlas source code and raw data 11 | The resources listed in the Generative AI Atlas are available in the `atlas.csv` file stored in the `public` folder. 12 | 13 | In case you want to run the web app locally, clone the repository and follow the steps below: 14 | 15 | Install the dependencies: 16 | ``` 17 | npm install 18 | ``` 19 | 20 | Start the project: 21 | ``` 22 | npm run start 23 | ``` 24 | 25 | ### Contributors 26 | This project is developed and maintaned by Luca Guida ([GitHub](https://github.com/l-guida), [Linkedin](https://www.linkedin.com/in/lucaguida/)), Chiara Relandini ([GitHub](https://github.com/chiararelandini), [Linkedin](https://www.linkedin.com/in/chiara-relandini-aa243a148/)) and Arian Rezai Tabrizi ([GitHub](https://github.com/arianrezai), [Linkedin](https://www.linkedin.com/in/arianrezai/)). 27 | -------------------------------------------------------------------------------- /THIRD_PARTY_LICENSES: -------------------------------------------------------------------------------- 1 | The "Generative AI Atlas" project includes the following third-party software/licensing: 2 | 3 | 4 | ** @cloudscape-design/components - https://github.com/cloudscape-design/components 5 | ** aws-amplify - https://github.com/aws-amplify 6 | 7 | 8 | Apache License 9 | Version 2.0, January 2004 10 | http://www.apache.org/licenses/ 11 | 12 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 13 | 14 | 1. Definitions. 15 | 16 | "License" shall mean the terms and conditions for use, reproduction, 17 | and distribution as defined by Sections 1 through 9 of this document. 18 | 19 | "Licensor" shall mean the copyright owner or entity authorized by 20 | the copyright owner that is granting the License. 21 | 22 | "Legal Entity" shall mean the union of the acting entity and all 23 | other entities that control, are controlled by, or are under common 24 | control with that entity. For the purposes of this definition, 25 | "control" means (i) the power, direct or indirect, to cause the 26 | direction or management of such entity, whether by contract or 27 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 28 | outstanding shares, or (iii) beneficial ownership of such entity. 29 | 30 | "You" (or "Your") shall mean an individual or Legal Entity 31 | exercising permissions granted by this License. 32 | 33 | "Source" form shall mean the preferred form for making modifications, 34 | including but not limited to software source code, documentation 35 | source, and configuration files. 36 | 37 | "Object" form shall mean any form resulting from mechanical 38 | transformation or translation of a Source form, including but 39 | not limited to compiled object code, generated documentation, 40 | and conversions to other media types. 41 | 42 | "Work" shall mean the work of authorship, whether in Source or 43 | Object form, made available under the License, as indicated by a 44 | copyright notice that is included in or attached to the work 45 | (an example is provided in the Appendix below). 46 | 47 | "Derivative Works" shall mean any work, whether in Source or Object 48 | form, that is based on (or derived from) the Work and for which the 49 | editorial revisions, annotations, elaborations, or other modifications 50 | represent, as a whole, an original work of authorship. For the purposes 51 | of this License, Derivative Works shall not include works that remain 52 | separable from, or merely link (or bind by name) to the interfaces of, 53 | the Work and Derivative Works thereof. 54 | 55 | "Contribution" shall mean any work of authorship, including 56 | the original version of the Work and any modifications or additions 57 | to that Work or Derivative Works thereof, that is intentionally 58 | submitted to Licensor for inclusion in the Work by the copyright owner 59 | or by an individual or Legal Entity authorized to submit on behalf of 60 | the copyright owner. For the purposes of this definition, "submitted" 61 | means any form of electronic, verbal, or written communication sent 62 | to the Licensor or its representatives, including but not limited to 63 | communication on electronic mailing lists, source code control systems, 64 | and issue tracking systems that are managed by, or on behalf of, the 65 | Licensor for the purpose of discussing and improving the Work, but 66 | excluding communication that is conspicuously marked or otherwise 67 | designated in writing by the copyright owner as "Not a Contribution." 68 | 69 | "Contributor" shall mean Licensor and any individual or Legal Entity 70 | on behalf of whom a Contribution has been received by Licensor and 71 | subsequently incorporated within the Work. 72 | 73 | 2. Grant of Copyright 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 | copyright license to reproduce, prepare Derivative Works of, 77 | publicly display, publicly perform, sublicense, and distribute the 78 | Work and such Derivative Works in Source or Object form. 79 | 80 | 3. Grant of Patent License. Subject to the terms and conditions of 81 | this License, each Contributor hereby grants to You a perpetual, 82 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 83 | (except as stated in this section) patent license to make, have made, 84 | use, offer to sell, sell, import, and otherwise transfer the Work, 85 | where such license applies only to those patent claims licensable 86 | by such Contributor that are necessarily infringed by their 87 | Contribution(s) alone or by combination of their Contribution(s) 88 | with the Work to which such Contribution(s) was submitted. If You 89 | institute patent litigation against any entity (including a 90 | cross-claim or counterclaim in a lawsuit) alleging that the Work 91 | or a Contribution incorporated within the Work constitutes direct 92 | or contributory patent infringement, then any patent licenses 93 | granted to You under this License for that Work shall terminate 94 | as of the date such litigation is filed. 95 | 96 | 4. Redistribution. You may reproduce and distribute copies of the 97 | Work or Derivative Works thereof in any medium, with or without 98 | modifications, and in Source or Object form, provided that You 99 | meet the following conditions: 100 | 101 | (a) You must give any other recipients of the Work or 102 | Derivative Works a copy of this License; and 103 | 104 | (b) You must cause any modified files to carry prominent notices 105 | stating that You changed the files; and 106 | 107 | (c) You must retain, in the Source form of any Derivative Works 108 | that You distribute, all copyright, patent, trademark, and 109 | attribution notices from the Source form of the Work, 110 | excluding those notices that do not pertain to any part of 111 | the Derivative Works; and 112 | 113 | (d) If the Work includes a "NOTICE" text file as part of its 114 | distribution, then any Derivative Works that You distribute must 115 | include a readable copy of the attribution notices contained 116 | within such NOTICE file, excluding those notices that do not 117 | pertain to any part of the Derivative Works, in at least one 118 | of the following places: within a NOTICE text file distributed 119 | as part of the Derivative Works; within the Source form or 120 | documentation, if provided along with the Derivative Works; or, 121 | within a display generated by the Derivative Works, if and 122 | wherever such third-party notices normally appear. The contents 123 | of the NOTICE file are for informational purposes only and 124 | do not modify the License. You may add Your own attribution 125 | notices within Derivative Works that You distribute, alongside 126 | or as an addendum to the NOTICE text from the Work, provided 127 | that such additional attribution notices cannot be construed 128 | as modifying the License. 129 | 130 | You may add Your own copyright statement to Your modifications and 131 | may provide additional or different license terms and conditions 132 | for use, reproduction, or distribution of Your modifications, or 133 | for any such Derivative Works as a whole, provided Your use, 134 | reproduction, and distribution of the Work otherwise complies with 135 | the conditions stated in this License. 136 | 137 | 5. Submission of Contributions. Unless You explicitly state otherwise, 138 | any Contribution intentionally submitted for inclusion in the Work 139 | by You to the Licensor shall be under the terms and conditions of 140 | this License, without any additional terms or conditions. 141 | Notwithstanding the above, nothing herein shall supersede or modify 142 | the terms of any separate license agreement you may have executed 143 | with Licensor regarding such Contributions. 144 | 145 | 6. Trademarks. This License does not grant permission to use the trade 146 | names, trademarks, service marks, or product names of the Licensor, 147 | except as required for reasonable and customary use in describing the 148 | origin of the Work and reproducing the content of the NOTICE file. 149 | 150 | 7. Disclaimer of Warranty. Unless required by applicable law or 151 | agreed to in writing, Licensor provides the Work (and each 152 | Contributor provides its Contributions) on an "AS IS" BASIS, 153 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 154 | implied, including, without limitation, any warranties or conditions 155 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 156 | PARTICULAR PURPOSE. You are solely responsible for determining the 157 | appropriateness of using or redistributing the Work and assume any 158 | risks associated with Your exercise of permissions under this License. 159 | 160 | 8. Limitation of Liability. In no event and under no legal theory, 161 | whether in tort (including negligence), contract, or otherwise, 162 | unless required by applicable law (such as deliberate and grossly 163 | negligent acts) or agreed to in writing, shall any Contributor be 164 | liable to You for damages, including any direct, indirect, special, 165 | incidental, or consequential damages of any character arising as a 166 | result of this License or out of the use or inability to use the 167 | Work (including but not limited to damages for loss of goodwill, 168 | work stoppage, computer failure or malfunction, or any and all 169 | other commercial damages or losses), even if such Contributor 170 | has been advised of the possibility of such damages. 171 | 172 | 9. Accepting Warranty or Additional Liability. While redistributing 173 | the Work or Derivative Works thereof, You may choose to offer, 174 | and charge a fee for, acceptance of support, warranty, indemnity, 175 | or other liability obligations and/or rights consistent with this 176 | License. However, in accepting such obligations, You may act only 177 | on Your own behalf and on Your sole responsibility, not on behalf 178 | of any other Contributor, and only if You agree to indemnify, 179 | defend, and hold each Contributor harmless for any liability 180 | incurred by, or claims asserted against, such Contributor by reason 181 | of your accepting any such warranty or additional liability. 182 | 183 | 184 | ---------------- 185 | 186 | ** papaparse - https://github.com/mholt/PapaParse 187 | ** react - https://github.com/facebook/react 188 | ** react-image-size - https://github.com/andreyk1512/react-image-size 189 | ** react-router-dom - https://github.com/remix-run/react-router 190 | ** react-dom - https://github.com/facebook/react 191 | ** next - https://github.com/vercel/next.js 192 | 193 | 194 | The MIT License (MIT) 195 | Copyright (c) 2017 Kent C. Dodds 196 | 197 | Permission is hereby granted, free of charge, to any person obtaining a copy 198 | of this software and associated documentation files (the "Software"), to deal 199 | in the Software without restriction, including without limitation the rights 200 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 201 | copies of the Software, and to permit persons to whom the Software is 202 | furnished to do so, subject to the following conditions: 203 | 204 | The above copyright notice and this permission notice shall be included in all 205 | copies or substantial portions of the Software. 206 | 207 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 208 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 209 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 210 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 211 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 212 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 213 | SOFTWARE. 214 | -------------------------------------------------------------------------------- /amplify.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | frontend: 3 | phases: 4 | preBuild: 5 | commands: 6 | - nvm install v20.12.0 7 | - nvm use v20.12.0 8 | - npm ci --cache .npm --prefer-offline 9 | build: 10 | commands: 11 | - nvm install v20.12.0 12 | - nvm use v20.12.0 13 | - npm run build 14 | artifacts: 15 | baseDirectory: .next 16 | files: 17 | - '**/*' 18 | cache: 19 | paths: 20 | - .next/cache/**/* 21 | - .npm/**/* 22 | - node_modules/**/* 23 | -------------------------------------------------------------------------------- /app/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/components/Breadcrumbs.js: -------------------------------------------------------------------------------- 1 | import { BreadcrumbGroup } from "@cloudscape-design/components" 2 | 3 | export const HomeBreadcrumbs = () => { 4 | return 11 | } 12 | -------------------------------------------------------------------------------- /app/components/Cards.js: -------------------------------------------------------------------------------- 1 | import { Box, Button } from "@cloudscape-design/components"; 2 | 3 | export const CardsNoMatchState = props => ( 4 | 5 | No matches 6 | 11 | We can't find a match. 12 | 13 | 14 | 15 | ); 16 | 17 | export const CardsEmptyState = () => ( 18 | 19 | No resources 20 | 25 | No resources to display. 26 | 27 | 28 | 29 | ); -------------------------------------------------------------------------------- /app/components/Labels.js: -------------------------------------------------------------------------------- 1 | export const appLayoutLabels = { 2 | navigation: 'Side navigation', 3 | navigationToggle: 'Open side navigation', 4 | navigationClose: 'Close side navigation', 5 | notifications: 'Notifications', 6 | tools: 'Help panel', 7 | toolsToggle: 'Open help panel', 8 | toolsClose: 'Close help panel' 9 | }; -------------------------------------------------------------------------------- /app/components/Navigation.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import SideNavigation from "@cloudscape-design/components/side-navigation"; 3 | import { useLocation, useNavigate } from "react-router-dom"; 4 | import { useCheckMobileScreen } from "./utils" 5 | 6 | export const navHeader = { text: 'Generative AI Atlas', href: '/' }; 7 | export const navItems = [ 8 | { 9 | type: 'section', 10 | text: 'Use Cases and Resources', 11 | items: [ 12 | { type: 'link', text: 'Explore and Search', href: '/' }, 13 | ] 14 | } 15 | ]; 16 | 17 | function Navigation(props) { 18 | const navigate = useNavigate(); 19 | const location = useLocation(); 20 | const isMobile = useCheckMobileScreen(); 21 | function onFollowHandler(ev) { 22 | if (ev.detail.href) { 23 | if (!ev.detail.external) { 24 | ev.preventDefault(); 25 | navigate(ev.detail.href); 26 | if(isMobile){ 27 | props.setNavigationOpen(false) 28 | } 29 | } 30 | } 31 | } 32 | return ( 33 | 39 | ); 40 | } 41 | 42 | export default Navigation; -------------------------------------------------------------------------------- /app/components/constants.js: -------------------------------------------------------------------------------- 1 | export const contentTypeMapping = { 2 | 'blog': 'Blog Post', 3 | 'workshop': 'Hands-on Workshop', 4 | 'jumpstart': 'SageMaker JumpStart', 5 | 'solution': 'AWS Solution', 6 | 'video': 'Video' 7 | } 8 | 9 | export const useCaseMapping = { 10 | 'text-generation': 'Text Generation', 11 | 'summarization-paraphrasing': 'Summarization & Paraphrasing', 12 | 'search': 'Search', 13 | 'chat': 'Chat', 14 | 'code-generation': 'Code Generation', 15 | 'question-answering': 'Question Answering', 16 | 'sentiment-analysis': 'Sentiment Analysis', 17 | 'image-generation': 'Image Generation', 18 | 'image-to-text': 'Image-to-Text', 19 | 'personalization': 'Personalization', 20 | 'fine-tuning': 'Model Fine Tuning', 21 | 'classification-NER': 'Named Entity Recognition & Classification', 22 | 'best-practices': 'Generative AI Best Practices', 23 | 'vector-database': 'Vector Database', 24 | 'RAG': 'Retrieval Augmented Generation' 25 | } 26 | 27 | export const useCasesOptions = [ 28 | // this should better be dynamic 29 | { label: 'text-generation', value: '1' }, 30 | { label: 'summarization-paraphrasing', value: '2' }, 31 | { label: 'search', value: '3' }, 32 | { label: 'chat', value: '4' }, 33 | { label: 'code-generation', value: '5' }, 34 | { label: 'question-answering', value: '6' }, 35 | { label: 'sentiment-analysis', value: '7' }, 36 | { label: 'image-generation', value: '8' }, 37 | { label: 'image-to-text', value: '9' }, 38 | { label: 'personalization', value: '10' }, 39 | { label: 'fine-tuning', value: '11' }, 40 | { label: 'classification-NER', value: '12' }, 41 | { label: 'best-practices', value: '13'}, 42 | { label: 'vector-database', value: '14' }, 43 | { label: 'RAG', value: '15'} 44 | ] 45 | 46 | export const contentTypesOptions = [ 47 | // this should better be dynamic 48 | { label: 'blog', value: '1' }, 49 | { label: 'workshop', value: '2' }, 50 | { label: 'jumpstart', value: '3' }, 51 | { label: 'solution', value: '4' }, 52 | { label: 'video', value: '5' } 53 | ] 54 | 55 | export const SEARCHABLE_COLUMNS_CARDS = [ 'name', 'url', 'useCases', 'type', 'update', 'imageUrl' ] 56 | 57 | export const cardsVisiblePreferencesOptions = [ 58 | { id: "url", label: "Url" }, 59 | { id: "useCases", label: "Use cases" }, 60 | { id: "type", label: "Content type" }, 61 | { id: "update", label: "Date" }, 62 | { id: "image", label: "Image" } 63 | ] 64 | export const cardsVisibleContent = [ "url", "useCases", "type", "update", "image" ] 65 | -------------------------------------------------------------------------------- /app/components/utils.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { getImageSize } from 'react-image-size'; 3 | import { contentTypeMapping, contentTypesOptions, useCaseMapping, useCasesOptions } from "./constants"; 4 | 5 | export const useCheckMobileScreen = () => { 6 | const [width, setWidth] = useState(window.innerWidth); 7 | const handleWindowSizeChange = () => { 8 | setWidth(window.innerWidth); 9 | } 10 | 11 | useEffect(() => { 12 | window.addEventListener('resize', handleWindowSizeChange); 13 | return () => { 14 | window.removeEventListener('resize', handleWindowSizeChange); 15 | } 16 | }, []); 17 | 18 | return (width <= 768); 19 | } 20 | 21 | const getImgDim = async (imageUrl) => { 22 | let imgDim = null 23 | try{ 24 | imgDim = imageUrl ? await getImageSize(imageUrl) : null 25 | }catch(err){ 26 | console.log("error") 27 | console.log(err) 28 | imgDim = null 29 | } 30 | return imgDim 31 | } 32 | 33 | export const mapContentTypeName = (typeName) => { 34 | const mapped = contentTypeMapping[typeName] 35 | if(!mapped){ 36 | console.error('ERROR: missing mapping for content type label:', typeName) 37 | } 38 | return mapped 39 | } 40 | 41 | const mapUseCaseName = (useCaseName) => { 42 | const mapped = useCaseMapping[useCaseName] 43 | if(!mapped){ 44 | console.error('ERROR: missing mapping for use case label:', useCaseName) 45 | } 46 | return mapped 47 | } 48 | 49 | export const aggregateUseCases = (useCases) => { 50 | return useCases?.map(mapUseCaseName)?.join(", ") || "" 51 | } 52 | 53 | const collectUseCases = (resource) => { 54 | 55 | const useCaseLabels = ["Use case 1", "Use case 2", "Use case 3", "Use case 4", "Use case 5", "Use case 6", "Use case 7", "Use case 8", "Use case 9", "Use case 10"] 56 | 57 | const useCases = [] 58 | useCaseLabels.forEach(label => { 59 | if(resource?.[label]?.length > 0){ 60 | useCases.push(resource?.[label]) 61 | } 62 | }) 63 | return useCases 64 | 65 | } 66 | 67 | export const mapResourceFields = async (resource) => { 68 | if(!resource || !resource["Content title"]){ return {} } 69 | 70 | const imageUrl = resource["Image URL"] === "Notebook icon TBD" ? null : resource["Image URL"] 71 | const imgDim = await getImgDim(imageUrl) 72 | 73 | return { 74 | name: resource["Content title"], 75 | alt: "First", 76 | url: resource.URL, 77 | useCases: collectUseCases(resource), 78 | type: resource["Content type"], 79 | update: resource["Publication date (MM/DD/YYYY)"], 80 | imageUrl, 81 | imgDim 82 | } 83 | } 84 | 85 | export const prepareUseCasesOptions = () => [...useCasesOptions.map(option => ({ ...option, rawLabel: option.label, label: mapUseCaseName(option.label)}))] 86 | 87 | export const prepareContentTypesOptions = (defaultContentType) => [defaultContentType, ...contentTypesOptions.map(option => ({...option, rawLabel: option.label, label: mapContentTypeName(option.label)}))] 88 | 89 | export const includesUseCase = (useCases, selectedUseCases) => { 90 | // if no use cases have been selected, return true 91 | let match = selectedUseCases?.length === 0 || false 92 | selectedUseCases.filter(selectedUseCase => selectedUseCase?.rawLabel != null).forEach(selectedUseCase => { 93 | if(useCases?.includes(selectedUseCase?.rawLabel)){ 94 | match = true 95 | return 96 | } 97 | }) 98 | return match 99 | } 100 | 101 | export const getTextFilterCounterText = (count) => `${count} ${count === 1 ? 'match' : 'matches'}` 102 | 103 | export const paginationAriaLabels = (totalPages) => ({ 104 | nextPageLabel: 'Next page', 105 | previousPageLabel: 'Previous page', 106 | pageLabel: pageNumber => `Page ${pageNumber} of ${totalPages || 'all pages'}`, 107 | }) 108 | 109 | export const getNumberOfVisibleItems = (filteredItemsCount, currentPage, totalPages, pageSize, totalResources) => { 110 | return filteredItemsCount 111 | ? `(${filteredItemsCount}/${totalResources})` 112 | : `(${totalResources})` 113 | } 114 | 115 | export const getUseCaseFromQueryParamIfExists = (param) => { 116 | const array = JSON.parse(JSON.stringify("[" + (param || '') + "]")) 117 | const selectUseCaseOptions = prepareUseCasesOptions() 118 | return selectUseCaseOptions.filter(option => array?.includes(option.rawLabel)) || [] 119 | } 120 | 121 | export const getContentTypeFromQueryParamIfExists = (param, defaultContentType) => { 122 | const selectContentTypesOptions = prepareContentTypesOptions(defaultContentType); 123 | return selectContentTypesOptions.filter(option => option.rawLabel === param)?.[0] || defaultContentType 124 | } -------------------------------------------------------------------------------- /app/containers/LandingPage.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useEffect } from 'react'; 4 | import { useSearchParams } from 'react-router-dom'; 5 | 6 | import Cards from "@cloudscape-design/components/cards"; 7 | import Box from "@cloudscape-design/components/box"; 8 | import Header from "@cloudscape-design/components/header"; 9 | import Pagination from "@cloudscape-design/components/pagination"; 10 | import CollectionPreferences from "@cloudscape-design/components/collection-preferences"; 11 | import Link from "@cloudscape-design/components/link"; 12 | import { useCollection } from '@cloudscape-design/collection-hooks'; 13 | import { 14 | AppLayout, ColumnLayout, ContentLayout, FormField, Input, Multiselect, Select, SpaceBetween, 15 | } from "@cloudscape-design/components"; 16 | 17 | 18 | import Navigation from "../components/Navigation"; 19 | import { appLayoutLabels} from '../components/Labels'; 20 | import { aggregateUseCases, getContentTypeFromQueryParamIfExists, getNumberOfVisibleItems, getTextFilterCounterText, getUseCaseFromQueryParamIfExists, includesUseCase, mapContentTypeName, mapResourceFields, paginationAriaLabels, prepareContentTypesOptions, prepareUseCasesOptions } from '../components/utils' 21 | import { CardsEmptyState, CardsNoMatchState } from '../components/Cards'; 22 | import { SEARCHABLE_COLUMNS_CARDS, cardsVisibleContent, cardsVisiblePreferencesOptions } from '../components/constants'; 23 | 24 | import Papa from "papaparse"; 25 | import { HomeBreadcrumbs } from '../components/Breadcrumbs'; 26 | const csvFile = '/atlas.csv' 27 | const rectangle = '/rectangle_grey.png' 28 | const repoImage = '/image.png' 29 | 30 | const defaultUseCase = { value: '0', label: 'Any use case', rawLabel: 'default' }; 31 | const defaultContentType = { value: '0', label: 'Any content type', rawLabel: 'default' }; 32 | 33 | const selectUseCaseOptions = prepareUseCasesOptions(); 34 | const selectContentTypesOptions = prepareContentTypesOptions(defaultContentType); 35 | 36 | function matchesUseCase(item, selectedUseCase) { 37 | return includesUseCase(item.useCases, selectedUseCase) 38 | } 39 | 40 | function matchesContentType(item, selectedContentType) { 41 | return selectedContentType === defaultContentType || item.type === selectedContentType.rawLabel 42 | } 43 | 44 | const CardsContent = () => { 45 | const [searchParams, setSearchParams] = useSearchParams(); 46 | 47 | const [ loading, setLoading ] = React.useState(false); 48 | const [ selectedItems, setSelectedItems ] = React.useState([{ }]); 49 | const [ preferences, setPreferences ] = React.useState({ pageSize: 12, visibleContent: cardsVisibleContent }) 50 | const [ resources, setResources ] = React.useState([]) 51 | const [ useCases, setUseCases ] = React.useState([]); 52 | const [ contentType, setContentType ] = React.useState(defaultContentType); 53 | 54 | useEffect(() => { 55 | const fetchData = async () => { 56 | setLoading(true) 57 | 58 | Papa.parse(csvFile, { 59 | header: true, 60 | skipEmptyLines: true, 61 | download: true, 62 | 63 | error: function(error) { 64 | console.log("Error in loading the CSV file") 65 | console.log(error.message); 66 | console.log(csvFile) 67 | }, 68 | 69 | complete: async function (results) { 70 | const rowsArray = []; 71 | 72 | results.data.forEach((d) => { 73 | rowsArray.push(Object.keys(d)); 74 | }); 75 | 76 | const transformedResults = await Promise.all( 77 | results.data?.filter(res => res?.["Content title"]) 78 | ?.map( 79 | async res => await mapResourceFields(res)) 80 | ) 81 | console.log({transformedResults}) 82 | setResources(transformedResults) 83 | 84 | setLoading(false) 85 | }, 86 | }); 87 | } 88 | 89 | fetchData().catch(console.error); 90 | 91 | const searchUseCaseValue = searchParams.get('use-case'); 92 | const useCasesToSelect = getUseCaseFromQueryParamIfExists(searchUseCaseValue) 93 | setUseCases(useCasesToSelect) 94 | 95 | const searchContentTypeValue = searchParams.get('content-type'); 96 | const contentTypeToSelect = getContentTypeFromQueryParamIfExists(searchContentTypeValue, defaultContentType) 97 | setContentType(contentTypeToSelect) 98 | 99 | const searchText = searchParams.get('text') 100 | if(searchText){ actions.setFiltering(searchText) } 101 | 102 | const refinedQuery = { 103 | ...(searchUseCaseValue ? {useCaseQuery: useCasesToSelect?.map(c => c?.rawLabel)}: {}), 104 | ...(searchContentTypeValue ? {contentTypeQuery: contentTypeToSelect?.rawLabel}: {}), 105 | textFilter: searchText 106 | } 107 | addQueryParams(refinedQuery) 108 | 109 | }, []) 110 | 111 | const { items, actions, filteredItemsCount, filterProps, paginationProps } = useCollection( 112 | resources, 113 | { 114 | filtering: { 115 | empty: , 116 | noMatch: , 117 | filteringFunction: (item, filteringText) => { 118 | if (!matchesUseCase(item, useCases)) { 119 | return false; 120 | } 121 | 122 | if (!matchesContentType(item, contentType)) { 123 | return false; 124 | } 125 | 126 | const filteringTextLowerCase = filteringText.toLowerCase(); 127 | return SEARCHABLE_COLUMNS_CARDS.map(key => item[key]).some( 128 | value => typeof value === 'string' && value.toLowerCase().indexOf(filteringTextLowerCase) > -1 129 | ); 130 | }, 131 | }, 132 | pagination: { pageSize: preferences.pageSize }, 133 | selection: {}, 134 | } 135 | ); 136 | 137 | function clearFilter() { 138 | actions.setFiltering(''); 139 | setUseCases([]); 140 | setContentType(defaultContentType); 141 | } 142 | 143 | const addQueryParams = (query) => { 144 | const { textFilter, useCaseQuery, contentTypeQuery } = query 145 | const useCaseParam = (useCaseQuery || useCases?.map(c => c.rawLabel) || []).join() 146 | const contentTypeParam = contentTypeQuery || contentType?.rawLabel 147 | const textParam = textFilter ?? filterProps.filteringText 148 | 149 | const queryParams = { 150 | ...(textParam ? { "text": textParam } : {} ), 151 | ...(useCaseParam?.length > 0 ? { "use-case": useCaseParam } : {} ), 152 | ...(contentTypeParam !== defaultContentType.rawLabel ? { "content-type": contentTypeParam } : {} ) 153 | } 154 | 155 | setSearchParams(queryParams) 156 | } 157 | 158 | return ( 159 | 161 | setSelectedItems(detail.selectedItems) 162 | } 163 | selectedItems={selectedItems} 164 | ariaLabels={{ 165 | itemSelectionLabel: (e, n) => `select ${n.name}`, 166 | selectionGroupLabel: "Item selection" 167 | }} 168 | stickyHeader={false} 169 | cardDefinition={{ 170 | header: e => e.name, 171 | sections: [ 172 | { 173 | id: "image", 174 | content: e => 175 | { 176 | let width = '100%' 177 | if(e.imageUrl && (e.imgDim?.width < e.imgDim?.height)){ 178 | width = '50%' 179 | } 180 | 181 | return 182 | { 183 | !e.imgDim ? 184 | : 185 | 186 | } 187 | } 188 | }, 189 | { 190 | id: "url", 191 | content: e => Open 192 | }, 193 | { 194 | id: "useCases", 195 | header: "Use cases", 196 | content: e => aggregateUseCases(e.useCases) 197 | }, 198 | { 199 | id: "type", 200 | header: "Content type", 201 | content: e => mapContentTypeName(e.type), 202 | width: 50 203 | }, 204 | { 205 | id: "update", 206 | header: "Date", 207 | content: e => e.update, 208 | width: 50 209 | }, 210 | ] 211 | }} 212 | cardsPerRow={[ 213 | { cards: 1 }, 214 | { minWidth: 500, cards: 2 }, 215 | { minWidth: 800, cards: 3 }, 216 | { minWidth: 1200, cards: 4 } 217 | ]} 218 | items={items} 219 | loading={loading} 220 | loadingText="Loading resources" 221 | trackBy="name" 222 | visibleSections={preferences.visibleContent} 223 | empty={ 224 | 225 | } 226 | filter={ 227 |
228 |
229 | 230 | { 235 | const textFilter = event.detail.value 236 | actions.setFiltering(textFilter); 237 | 238 | addQueryParams({ textFilter }) 239 | }} 240 | placeholder="Enter a keyword" 241 | clearAriaLabel="clear" 242 | ariaDescribedby={null} 243 | disabled={loading} 244 | /> 245 | 246 |
247 | 248 |
249 | 250 | { 256 | const selectedUseCases = event.detail.selectedOptions 257 | setUseCases(selectedUseCases); 258 | 259 | const useCaseQuery = selectedUseCases?.map(c => c?.rawLabel) 260 | addQueryParams({ useCaseQuery }) 261 | 262 | }} 263 | placeholder={defaultUseCase.label} 264 | ariaDescribedby={null} 265 | expandToViewport={true} 266 | /> 267 | 268 |
269 |
270 | 271 |