@salesforce/templates 66.11.1 → 66.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/lib/generators/projectGenerator.js +4 -1
  2. package/lib/generators/projectGenerator.js.map +1 -1
  3. package/lib/generators/uiEmbeddingGenerator.d.ts +6 -0
  4. package/lib/generators/{lightningEmbeddingGenerator.js → uiEmbeddingGenerator.js} +12 -12
  5. package/lib/generators/uiEmbeddingGenerator.js.map +1 -0
  6. package/lib/i18n/i18n.d.ts +6 -6
  7. package/lib/i18n/i18n.js +6 -6
  8. package/lib/i18n/i18n.js.map +1 -1
  9. package/lib/index.d.ts +1 -1
  10. package/lib/index.js +1 -1
  11. package/lib/index.js.map +1 -1
  12. package/lib/templates/project/angularextapp/.forceignore +15 -0
  13. package/lib/templates/project/angularextapp/.husky/pre-commit +4 -0
  14. package/lib/templates/project/angularextapp/.prettierignore +11 -0
  15. package/lib/templates/project/angularextapp/.prettierrc +17 -0
  16. package/lib/templates/project/angularextapp/CHANGELOG.md +4086 -0
  17. package/lib/templates/project/angularextapp/README.md +77 -0
  18. package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/angularextapp1.digitalExperience-meta.xml +11 -0
  19. package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/sfdc_cms__site/angularextapp1/_meta.json +5 -0
  20. package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/sfdc_cms__site/angularextapp1/content.json +10 -0
  21. package/lib/templates/project/angularextapp/_p_/_m_/_dc_/angularextapp1.digitalExperienceConfig-meta.xml +8 -0
  22. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
  23. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.postcssrc.json +5 -0
  24. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.prettierignore +8 -0
  25. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.prettierrc +12 -0
  26. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/CHANGELOG.md +4 -0
  27. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/README.md +85 -0
  28. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +101 -0
  29. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angularextapp.uibundle-meta.xml +8 -0
  30. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +15 -0
  31. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/esbuild/api-version.mjs +17 -0
  32. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +60 -0
  33. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/middleware/html.mjs +3 -0
  34. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/middleware/proxy.mjs +12 -0
  35. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +13600 -0
  36. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +56 -0
  37. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/playwright.config.ts +25 -0
  38. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/public/favicon.ico +0 -0
  39. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +30 -0
  40. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/account-search.service.ts +196 -0
  41. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountIndustries.ts +26 -0
  42. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountTypes.ts +26 -0
  43. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/getAccountDetail.ts +128 -0
  44. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/searchAccounts.ts +58 -0
  45. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts +184 -0
  46. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.ts +74 -0
  47. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/user-profile.service.ts +126 -0
  48. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.config.ts +22 -0
  49. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.html +1 -0
  50. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.routes.ts +77 -0
  51. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.spec.ts +18 -0
  52. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.ts +15 -0
  53. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.html +53 -0
  54. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.spec.ts +89 -0
  55. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.ts +81 -0
  56. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/_field-size.scss +42 -0
  57. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.html +31 -0
  58. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.ts +53 -0
  59. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.html +18 -0
  60. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.scss +112 -0
  61. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.ts +57 -0
  62. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.scss +34 -0
  63. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.ts +110 -0
  64. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.html +10 -0
  65. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.ts +26 -0
  66. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.html +25 -0
  67. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.scss +36 -0
  68. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.ts +41 -0
  69. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.html +34 -0
  70. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.scss +33 -0
  71. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.ts +66 -0
  72. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.html +37 -0
  73. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.ts +55 -0
  74. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.html +21 -0
  75. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.ts +36 -0
  76. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field-size.ts +8 -0
  77. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.html +19 -0
  78. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.scss +35 -0
  79. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.ts +36 -0
  80. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.html +3 -0
  81. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.ts +17 -0
  82. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.html +10 -0
  83. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.ts +37 -0
  84. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.html +41 -0
  85. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.ts +40 -0
  86. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.html +24 -0
  87. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.scss +35 -0
  88. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts +72 -0
  89. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.html +1 -0
  90. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.scss +23 -0
  91. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.ts +56 -0
  92. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.html +1 -0
  93. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.scss +28 -0
  94. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.ts +24 -0
  95. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts +35 -0
  96. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth/auth.guard.ts +50 -0
  97. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth/auth.service.ts +126 -0
  98. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-form/auth-form.html +34 -0
  99. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-form/auth-form.ts +94 -0
  100. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-layout/auth-layout.html +2 -0
  101. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-layout/auth-layout.ts +30 -0
  102. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/card-layout/card-layout.html +16 -0
  103. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/card-layout/card-layout.ts +40 -0
  104. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/config/authentication.config.ts +75 -0
  105. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/footer-link/footer-link.html +9 -0
  106. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/footer-link/footer-link.ts +26 -0
  107. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/menu/auth-menu/auth-menu.html +26 -0
  108. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/menu/auth-menu/auth-menu.ts +46 -0
  109. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/reactive-form-page.base.ts +50 -0
  110. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/session/session.html +55 -0
  111. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/session/session.ts +205 -0
  112. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/status-alert/status-alert.html +5 -0
  113. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/status-alert/status-alert.ts +52 -0
  114. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.html +5 -0
  115. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.scss +17 -0
  116. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.ts +35 -0
  117. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/auth-helpers.ts +68 -0
  118. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/auth-validators.ts +72 -0
  119. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/helpers.ts +85 -0
  120. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-time-servlet.ts +130 -0
  121. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-timeout.config.ts +83 -0
  122. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-timeout.service.ts +201 -0
  123. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.html +54 -0
  124. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.ts +40 -0
  125. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.html +23 -0
  126. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.ts +78 -0
  127. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.html +18 -0
  128. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.ts +137 -0
  129. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.html +11 -0
  130. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.ts +69 -0
  131. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.html +11 -0
  132. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.ts +36 -0
  133. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.html +10 -0
  134. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
  135. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
  136. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.ts +146 -0
  137. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.html +8 -0
  138. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.ts +82 -0
  139. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.html +12 -0
  140. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.ts +65 -0
  141. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.html +12 -0
  142. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.ts +90 -0
  143. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/object-search-state.service.ts +232 -0
  144. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.html +8 -0
  145. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.ts +61 -0
  146. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.html +59 -0
  147. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.ts +108 -0
  148. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.html +50 -0
  149. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.ts +72 -0
  150. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/debounce.ts +31 -0
  151. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/field-utils.ts +54 -0
  152. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/filter-utils.ts +354 -0
  153. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/index.ts +12 -0
  154. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/sort-utils.ts +46 -0
  155. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.html +164 -0
  156. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.scss +7 -0
  157. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.ts +196 -0
  158. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.html +111 -0
  159. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.ts +217 -0
  160. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/change-password/change-password-page.html +68 -0
  161. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/change-password/change-password-page.ts +82 -0
  162. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/forgot-password/forgot-password-page.html +35 -0
  163. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/forgot-password/forgot-password-page.ts +87 -0
  164. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.html +18 -0
  165. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.ts +47 -0
  166. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.html +6 -0
  167. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.spec.ts +23 -0
  168. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.ts +13 -0
  169. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/login/login-page.html +47 -0
  170. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/login/login-page.ts +89 -0
  171. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.html +12 -0
  172. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.spec.ts +33 -0
  173. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.ts +15 -0
  174. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/profile/profile-page.html +116 -0
  175. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/profile/profile-page.ts +194 -0
  176. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/register/register-page.html +80 -0
  177. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/register/register-page.ts +93 -0
  178. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/reset-password/reset-password-page.html +60 -0
  179. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/reset-password/reset-password-page.ts +96 -0
  180. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/utils/async-data.ts +99 -0
  181. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/index.html +14 -0
  182. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/main.ts +5 -0
  183. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/styles.scss +170 -0
  184. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/theme.scss +39 -0
  185. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/types/sf-globals.d.ts +9 -0
  186. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.app.json +11 -0
  187. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.json +33 -0
  188. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.spec.json +10 -0
  189. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
  190. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleAuthUtils.cls +68 -0
  191. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleAuthUtils.cls-meta.xml +5 -0
  192. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleChangePassword.cls +77 -0
  193. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleChangePassword.cls-meta.xml +5 -0
  194. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleForgotPassword.cls +71 -0
  195. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleForgotPassword.cls-meta.xml +5 -0
  196. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleLogin.cls +105 -0
  197. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleLogin.cls-meta.xml +5 -0
  198. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleRegistration.cls +162 -0
  199. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleRegistration.cls-meta.xml +5 -0
  200. package/lib/templates/project/angularextapp/_p_/_m_/networks/angularextapp.network-meta.xml +60 -0
  201. package/lib/templates/project/angularextapp/_p_/_m_/package.xml +24 -0
  202. package/lib/templates/project/angularextapp/_p_/_m_/permissionsets/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +9 -0
  203. package/lib/templates/project/angularextapp/_p_/_m_/sites/angularextapp.site-meta.xml +31 -0
  204. package/lib/templates/project/angularextapp/config/project-scratch-def.json +13 -0
  205. package/lib/templates/project/angularextapp/eslint.config.js +7 -0
  206. package/lib/templates/project/angularextapp/jest.config.js +6 -0
  207. package/lib/templates/project/angularextapp/package.json +46 -0
  208. package/lib/templates/project/angularextapp/scripts/apex/hello.apex +10 -0
  209. package/lib/templates/project/angularextapp/scripts/gitignore-templates.json +4 -0
  210. package/lib/templates/project/angularextapp/scripts/graphql-search.sh +191 -0
  211. package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +103 -0
  212. package/lib/templates/project/angularextapp/scripts/org-setup-dev.mjs +87 -0
  213. package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +369 -0
  214. package/lib/templates/project/angularextapp/scripts/org-setup-xml.mjs +182 -0
  215. package/lib/templates/project/angularextapp/scripts/org-setup.config.json +9 -0
  216. package/lib/templates/project/angularextapp/scripts/org-setup.mjs +1702 -0
  217. package/lib/templates/project/angularextapp/scripts/sf-project-setup.mjs +103 -0
  218. package/lib/templates/project/angularextapp/scripts/soql/account.soql +6 -0
  219. package/lib/templates/project/angularextapp/scripts/validate-org-setup-config.mjs +38 -0
  220. package/lib/templates/project/angularextapp/sfdx-project.json +12 -0
  221. package/lib/templates/project/angularintapp/.forceignore +15 -0
  222. package/lib/templates/project/angularintapp/.husky/pre-commit +4 -0
  223. package/lib/templates/project/angularintapp/.prettierignore +11 -0
  224. package/lib/templates/project/angularintapp/.prettierrc +17 -0
  225. package/lib/templates/project/angularintapp/CHANGELOG.md +4086 -0
  226. package/lib/templates/project/angularintapp/README.md +77 -0
  227. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
  228. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.postcssrc.json +5 -0
  229. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.prettierignore +8 -0
  230. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.prettierrc +12 -0
  231. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/CHANGELOG.md +4 -0
  232. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/README.md +85 -0
  233. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +101 -0
  234. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angularintapp.uibundle-meta.xml +8 -0
  235. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +15 -0
  236. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/esbuild/api-version.mjs +17 -0
  237. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +60 -0
  238. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/middleware/html.mjs +3 -0
  239. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/middleware/proxy.mjs +12 -0
  240. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +13619 -0
  241. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +57 -0
  242. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/playwright.config.ts +25 -0
  243. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/public/favicon.ico +0 -0
  244. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +30 -0
  245. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/account-search.service.ts +196 -0
  246. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountIndustries.ts +26 -0
  247. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountTypes.ts +26 -0
  248. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/getAccountDetail.ts +128 -0
  249. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/searchAccounts.ts +58 -0
  250. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts +184 -0
  251. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.ts +74 -0
  252. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.config.ts +22 -0
  253. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.html +1 -0
  254. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.routes.ts +31 -0
  255. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.spec.ts +18 -0
  256. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.ts +15 -0
  257. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.html +52 -0
  258. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.spec.ts +90 -0
  259. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.ts +67 -0
  260. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/_field-size.scss +42 -0
  261. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.html +31 -0
  262. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.ts +53 -0
  263. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.html +18 -0
  264. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.scss +112 -0
  265. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.ts +57 -0
  266. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.scss +34 -0
  267. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.ts +110 -0
  268. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.html +10 -0
  269. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.ts +26 -0
  270. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.html +25 -0
  271. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.scss +36 -0
  272. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.ts +41 -0
  273. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.html +34 -0
  274. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.scss +33 -0
  275. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.ts +66 -0
  276. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.html +37 -0
  277. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.ts +55 -0
  278. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.html +21 -0
  279. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.ts +36 -0
  280. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field-size.ts +8 -0
  281. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.html +19 -0
  282. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.scss +35 -0
  283. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.ts +36 -0
  284. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.html +3 -0
  285. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.ts +17 -0
  286. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.html +10 -0
  287. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.ts +37 -0
  288. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.html +41 -0
  289. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.ts +40 -0
  290. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.html +24 -0
  291. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.scss +35 -0
  292. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts +72 -0
  293. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.html +1 -0
  294. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.scss +23 -0
  295. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.ts +56 -0
  296. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.html +1 -0
  297. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.scss +28 -0
  298. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.ts +24 -0
  299. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts +35 -0
  300. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +177 -0
  301. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/conversation.html +3 -0
  302. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/conversation.ts +119 -0
  303. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.html +54 -0
  304. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.ts +40 -0
  305. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.html +23 -0
  306. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.ts +78 -0
  307. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.html +18 -0
  308. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.ts +137 -0
  309. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.html +11 -0
  310. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.ts +69 -0
  311. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.html +11 -0
  312. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.ts +36 -0
  313. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.html +10 -0
  314. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
  315. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
  316. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.ts +146 -0
  317. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.html +8 -0
  318. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.ts +82 -0
  319. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.html +12 -0
  320. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.ts +65 -0
  321. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.html +12 -0
  322. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.ts +90 -0
  323. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/object-search-state.service.ts +232 -0
  324. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.html +8 -0
  325. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.ts +61 -0
  326. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.html +59 -0
  327. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.ts +108 -0
  328. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.html +50 -0
  329. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.ts +72 -0
  330. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/debounce.ts +31 -0
  331. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/field-utils.ts +54 -0
  332. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/filter-utils.ts +354 -0
  333. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/index.ts +12 -0
  334. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/sort-utils.ts +46 -0
  335. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.html +164 -0
  336. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.scss +7 -0
  337. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.ts +196 -0
  338. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.html +111 -0
  339. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.ts +217 -0
  340. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.html +18 -0
  341. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.ts +47 -0
  342. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.html +6 -0
  343. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.spec.ts +23 -0
  344. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.ts +13 -0
  345. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.html +12 -0
  346. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.spec.ts +33 -0
  347. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.ts +15 -0
  348. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/types/conversation.ts +55 -0
  349. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/types/globals.d.ts +13 -0
  350. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/utils/async-data.ts +99 -0
  351. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/index.html +14 -0
  352. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/index.ts +15 -0
  353. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/main.ts +5 -0
  354. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/styles.scss +170 -0
  355. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/theme.scss +39 -0
  356. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/types/sf-globals.d.ts +9 -0
  357. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.app.json +11 -0
  358. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.json +33 -0
  359. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.spec.json +10 -0
  360. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
  361. package/lib/templates/project/angularintapp/_p_/_m_/applications/angularintapp.app-meta.xml +17 -0
  362. package/lib/templates/project/angularintapp/_p_/_m_/permissionsets/angularintapp_Access.permissionset-meta.xml +13 -0
  363. package/lib/templates/project/angularintapp/config/project-scratch-def.json +13 -0
  364. package/lib/templates/project/angularintapp/eslint.config.js +7 -0
  365. package/lib/templates/project/angularintapp/jest.config.js +6 -0
  366. package/lib/templates/project/angularintapp/package.json +46 -0
  367. package/lib/templates/project/angularintapp/scripts/apex/hello.apex +10 -0
  368. package/lib/templates/project/angularintapp/scripts/gitignore-templates.json +4 -0
  369. package/lib/templates/project/angularintapp/scripts/graphql-search.sh +191 -0
  370. package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +103 -0
  371. package/lib/templates/project/angularintapp/scripts/org-setup-dev.mjs +87 -0
  372. package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +369 -0
  373. package/lib/templates/project/angularintapp/scripts/org-setup-xml.mjs +182 -0
  374. package/lib/templates/project/angularintapp/scripts/org-setup.config.json +9 -0
  375. package/lib/templates/project/angularintapp/scripts/org-setup.mjs +1702 -0
  376. package/lib/templates/project/angularintapp/scripts/sf-project-setup.mjs +103 -0
  377. package/lib/templates/project/angularintapp/scripts/soql/account.soql +6 -0
  378. package/lib/templates/project/angularintapp/scripts/validate-org-setup-config.mjs +38 -0
  379. package/lib/templates/project/angularintapp/sfdx-project.json +12 -0
  380. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +601 -572
  381. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +601 -572
  382. package/lib/templates/uiBundles/angularbasic/package-lock.json +147 -168
  383. package/lib/templates/uiBundles/reactbasic/package-lock.json +601 -572
  384. package/lib/templates/{lightningembedding → uiembedding}/default/default.html +3 -3
  385. package/lib/templates/{lightningembedding → uiembedding}/default/default.js +1 -1
  386. package/lib/tsconfig.tsbuildinfo +1 -1
  387. package/lib/utils/types.d.ts +5 -5
  388. package/lib/utils/types.js +3 -3
  389. package/lib/utils/types.js.map +1 -1
  390. package/lib/utils/uiBundleTemplateUtils.js +10 -0
  391. package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
  392. package/lib/utils/uiEmbedding.d.ts +12 -0
  393. package/lib/utils/{lightningEmbedding.js → uiEmbedding.js} +7 -7
  394. package/lib/utils/uiEmbedding.js.map +1 -0
  395. package/package.json +4 -2
  396. package/lib/generators/lightningEmbeddingGenerator.d.ts +0 -6
  397. package/lib/generators/lightningEmbeddingGenerator.js.map +0 -1
  398. package/lib/utils/lightningEmbedding.d.ts +0 -12
  399. package/lib/utils/lightningEmbedding.js.map +0 -1
  400. /package/lib/templates/{lightningembedding → uiembedding}/default/default.css +0 -0
  401. /package/lib/templates/{lightningembedding → uiembedding}/default/default.js-meta.xml +0 -0
@@ -0,0 +1,184 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { DataClient } from './data-client.service';
3
+ import { createDataSDK } from '@salesforce/platform-sdk';
4
+
5
+ vi.mock('@salesforce/platform-sdk', () => ({
6
+ createDataSDK: vi.fn(),
7
+ }));
8
+
9
+ describe('DataClient', () => {
10
+ let service: DataClient;
11
+ let mockGraphqlQuery: ReturnType<typeof vi.fn>;
12
+ let mockGraphqlMutate: ReturnType<typeof vi.fn>;
13
+ let mockFetch: ReturnType<typeof vi.fn>;
14
+
15
+ beforeEach(async () => {
16
+ mockGraphqlQuery = vi.fn();
17
+ mockGraphqlMutate = vi.fn();
18
+ mockFetch = vi.fn();
19
+
20
+ vi.mocked(createDataSDK).mockResolvedValue({
21
+ graphql: {
22
+ query: mockGraphqlQuery,
23
+ mutate: mockGraphqlMutate,
24
+ },
25
+ fetch: mockFetch,
26
+ } as any);
27
+
28
+ await TestBed.configureTestingModule({
29
+ providers: [DataClient],
30
+ }).compileComponents();
31
+
32
+ service = TestBed.inject(DataClient);
33
+ });
34
+
35
+ afterEach(() => {
36
+ vi.clearAllMocks();
37
+ });
38
+
39
+ it('should create the service', () => {
40
+ expect(service).toBeTruthy();
41
+ expect(service).toBeInstanceOf(DataClient);
42
+ });
43
+
44
+ it('should route plain query operations to graphql.query and return result.data', async () => {
45
+ const operation = 'query { user { id name } }';
46
+ const expectedData = { user: { id: '123', name: 'Test User' } };
47
+ mockGraphqlQuery.mockResolvedValue({ data: expectedData });
48
+
49
+ const result = await service.execute(operation);
50
+
51
+ expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables: undefined });
52
+ expect(mockGraphqlMutate).not.toHaveBeenCalled();
53
+ expect(result).toEqual(expectedData);
54
+ });
55
+
56
+ it('should route anonymous query operations to graphql.query', async () => {
57
+ const operation = '{ user { id name } }';
58
+ const expectedData = { user: { id: '456', name: 'Anonymous User' } };
59
+ mockGraphqlQuery.mockResolvedValue({ data: expectedData });
60
+
61
+ const result = await service.execute(operation);
62
+
63
+ expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables: undefined });
64
+ expect(mockGraphqlMutate).not.toHaveBeenCalled();
65
+ expect(result).toEqual(expectedData);
66
+ });
67
+
68
+ it('should route mutation operations to graphql.mutate', async () => {
69
+ const operation = 'mutation { updateUser(id: "123", name: "New Name") { id name } }';
70
+ const expectedData = { updateUser: { id: '123', name: 'New Name' } };
71
+ mockGraphqlMutate.mockResolvedValue({ data: expectedData });
72
+
73
+ const result = await service.execute(operation);
74
+
75
+ expect(mockGraphqlMutate).toHaveBeenCalledWith({ mutation: operation, variables: undefined });
76
+ expect(mockGraphqlQuery).not.toHaveBeenCalled();
77
+ expect(result).toEqual(expectedData);
78
+ });
79
+
80
+ it('should detect mutation with leading GraphQL comment and route to graphql.mutate', async () => {
81
+ const operation = '# This is a comment\nmutation { deleteUser(id: "123") { success } }';
82
+ const expectedData = { deleteUser: { success: true } };
83
+ mockGraphqlMutate.mockResolvedValue({ data: expectedData });
84
+
85
+ const result = await service.execute(operation);
86
+
87
+ expect(mockGraphqlMutate).toHaveBeenCalledWith({ mutation: operation, variables: undefined });
88
+ expect(mockGraphqlQuery).not.toHaveBeenCalled();
89
+ expect(result).toEqual(expectedData);
90
+ });
91
+
92
+ it('should not treat query as mutation when comment contains "mutation" word', async () => {
93
+ const operation = '# this is not a mutation, just a query\nquery { user { id } }';
94
+ const expectedData = { user: { id: '789' } };
95
+ mockGraphqlQuery.mockResolvedValue({ data: expectedData });
96
+
97
+ const result = await service.execute(operation);
98
+
99
+ expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables: undefined });
100
+ expect(mockGraphqlMutate).not.toHaveBeenCalled();
101
+ expect(result).toEqual(expectedData);
102
+ });
103
+
104
+ it('should throw error when result.errors contains errors', async () => {
105
+ const operation = 'query { user { id } }';
106
+ mockGraphqlQuery.mockResolvedValue({
107
+ data: null,
108
+ errors: [{ message: 'Field not found' }, { message: 'Permission denied' }],
109
+ });
110
+
111
+ await expect(service.execute(operation)).rejects.toThrow(
112
+ 'GraphQL Error: Field not found; Permission denied',
113
+ );
114
+ });
115
+
116
+ it('should throw error when result.errors contains a single error', async () => {
117
+ const operation = 'query { user { id } }';
118
+ mockGraphqlQuery.mockResolvedValue({
119
+ data: null,
120
+ errors: [{ message: 'Unauthorized' }],
121
+ });
122
+
123
+ await expect(service.execute(operation)).rejects.toThrow('GraphQL Error: Unauthorized');
124
+ });
125
+
126
+ it('should throw error when result.data is null with no errors', async () => {
127
+ const operation = 'query { user { id } }';
128
+ mockGraphqlQuery.mockResolvedValue({ data: null });
129
+
130
+ await expect(service.execute(operation)).rejects.toThrow('GraphQL response data is null');
131
+ });
132
+
133
+ it('should pass variables through to graphql.query', async () => {
134
+ const operation = 'query GetUser($id: ID!) { user(id: $id) { id name } }';
135
+ const variables = { id: '999' };
136
+ const expectedData = { user: { id: '999', name: 'Variable User' } };
137
+ mockGraphqlQuery.mockResolvedValue({ data: expectedData });
138
+
139
+ const result = await service.execute(operation, variables);
140
+
141
+ expect(mockGraphqlQuery).toHaveBeenCalledWith({ query: operation, variables });
142
+ expect(result).toEqual(expectedData);
143
+ });
144
+
145
+ it('should pass variables through to graphql.mutate', async () => {
146
+ const operation =
147
+ 'mutation UpdateUser($id: ID!, $name: String!) { updateUser(id: $id, name: $name) { id name } }';
148
+ const variables = { id: '888', name: 'Updated Name' };
149
+ const expectedData = { updateUser: { id: '888', name: 'Updated Name' } };
150
+ mockGraphqlMutate.mockResolvedValue({ data: expectedData });
151
+
152
+ const result = await service.execute(operation, variables);
153
+
154
+ expect(mockGraphqlMutate).toHaveBeenCalledWith({ mutation: operation, variables });
155
+ expect(result).toEqual(expectedData);
156
+ });
157
+
158
+ it('should proxy fetch to sdk.fetch and return the raw Response', async () => {
159
+ const url = '/services/apexrest/auth/login';
160
+ const init: RequestInit = {
161
+ method: 'POST',
162
+ body: JSON.stringify({ email: 'a@b.com' }),
163
+ headers: { 'Content-Type': 'application/json' },
164
+ };
165
+ const expectedResponse = { ok: true, status: 200 } as Response;
166
+ mockFetch.mockResolvedValue(expectedResponse);
167
+
168
+ const response = await service.fetch(url, init);
169
+
170
+ expect(mockFetch).toHaveBeenCalledWith(url, init);
171
+ expect(response).toBe(expectedResponse);
172
+ });
173
+
174
+ it('should call fetch with no init when omitted', async () => {
175
+ const url = '/services/data/v64.0/chatter/users/me';
176
+ const expectedResponse = { ok: true, status: 200 } as Response;
177
+ mockFetch.mockResolvedValue(expectedResponse);
178
+
179
+ const response = await service.fetch(url);
180
+
181
+ expect(mockFetch).toHaveBeenCalledWith(url, undefined);
182
+ expect(response).toBe(expectedResponse);
183
+ });
184
+ });
@@ -0,0 +1,74 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { createDataSDK } from '@salesforce/platform-sdk';
3
+
4
+ /**
5
+ * True when the operation's first definition is a `mutation`. Strips GraphQL
6
+ * comments first so a leading `# ...` line can't mask the keyword. Queries
7
+ * (named or anonymous `{ ... }` shorthand) and subscriptions fall through to
8
+ * query().
9
+ */
10
+ function isMutation(operation: string): boolean {
11
+ return /^\s*mutation\b/.test(operation.replace(/#[^\n\r]*/g, ''));
12
+ }
13
+
14
+ /**
15
+ * The single data-access client for the app — a thin wrapper over
16
+ * `createDataSDK` that centralizes both of the SDK's surfaces:
17
+ *
18
+ * - `execute()` for GraphQL (routes mutations to `sdk.graphql.mutate` and
19
+ * everything else to `sdk.graphql.query`, with centralized error handling).
20
+ * Use with gql-tagged queries and generated operation types for type-safe
21
+ * calls.
22
+ * - `fetch()` for REST (proxies `sdk.fetch`, returning the raw `Response` so
23
+ * callers keep full control over response parsing / error shaping).
24
+ *
25
+ * Consumers inject this instead of calling `createDataSDK` directly, so the SDK
26
+ * bootstrap lives in exactly one place. Feature packages consume it via an
27
+ * `__inherit__data-client.service` stub (base wins at compose).
28
+ */
29
+ @Injectable({ providedIn: 'root' })
30
+ export class DataClient {
31
+ /**
32
+ * Executes a GraphQL operation and returns its `data`, throwing on GraphQL
33
+ * errors or a null payload.
34
+ */
35
+ async execute<TData, TVariables = Record<string, unknown>>(
36
+ operation: string,
37
+ variables?: TVariables,
38
+ ): Promise<TData> {
39
+ const data = await createDataSDK();
40
+ const result = isMutation(operation)
41
+ ? await data.graphql!.mutate<TData, TVariables>({
42
+ mutation: operation,
43
+ variables,
44
+ })
45
+ : await data.graphql!.query<TData, TVariables>({
46
+ query: operation,
47
+ variables,
48
+ });
49
+
50
+ if (result.errors?.length) {
51
+ const msg = result.errors.map((e) => e.message).join('; ');
52
+ throw new Error(`GraphQL Error: ${msg}`);
53
+ }
54
+
55
+ if (result.data == null) {
56
+ throw new Error('GraphQL response data is null');
57
+ }
58
+
59
+ return result.data;
60
+ }
61
+
62
+ /**
63
+ * Performs a REST request through the SDK's authenticated `fetch`, returning
64
+ * the raw `Response`. Callers parse the body / shape errors themselves (e.g.
65
+ * via `handleApiResponse`).
66
+ *
67
+ * @param input - The request URL (e.g. an Apex REST route).
68
+ * @param init - Standard `fetch` options (method, headers, body, …).
69
+ */
70
+ async fetch(input: string, init?: RequestInit): Promise<Response> {
71
+ const sdk = await createDataSDK();
72
+ return sdk.fetch!(input, init);
73
+ }
74
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { Injectable, inject } from "@angular/core";
7
+ // DataClient is provided by the base-angular-app. Consumed via the
8
+ // `__inherit__` stub in this same folder (app/api/); post-compose patches-cli
9
+ // strips the prefix so it resolves to the seeded base file at
10
+ // app/api/data-client.service.ts.
11
+ import { DataClient } from "./data-client.service";
12
+ import { flattenGraphQLRecord } from "../features/authentication/utils/helpers";
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Hand-written GraphQL query/mutation strings + wire types. Codegen is PARKED
16
+ // for the Angular port (same decision as object-search). The field selection,
17
+ // query/mutation shape, and variable structure mirror the React
18
+ // `userProfileApi.ts` byte-for-byte so behavior is identical.
19
+ // ---------------------------------------------------------------------------
20
+
21
+ const USER_PROFILE_FIELDS_FULL = `
22
+ Id
23
+ FirstName @optional { value }
24
+ LastName @optional { value }
25
+ Email @optional { value }
26
+ Phone @optional { value }
27
+ Street @optional { value }
28
+ City @optional { value }
29
+ State @optional { value }
30
+ PostalCode @optional { value }
31
+ Country @optional { value }`;
32
+
33
+ const USER_CONTACT_FIELDS = `
34
+ Id
35
+ ContactId @optional { value }`;
36
+
37
+ function getUserProfileQuery(fields: string): string {
38
+ return `
39
+ query GetUserProfile($userId: ID) {
40
+ uiapi {
41
+ query {
42
+ User(where: { Id: { eq: $userId } }) {
43
+ edges {
44
+ node {${fields}}
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }`;
50
+ }
51
+
52
+ function getUserProfileMutation(fields: string): string {
53
+ return `
54
+ mutation UpdateUserProfile($input: UserUpdateInput!) {
55
+ uiapi {
56
+ UserUpdate(input: $input) {
57
+ Record {${fields}}
58
+ }
59
+ }
60
+ }`;
61
+ }
62
+
63
+ /** Wire shape for the GetUserProfile query. */
64
+ interface GetUserProfileData {
65
+ uiapi: {
66
+ query: {
67
+ User: { edges: Array<{ node: Record<string, unknown> } | null> | null } | null;
68
+ };
69
+ };
70
+ }
71
+
72
+ /** Wire shape for the UpdateUserProfile mutation. */
73
+ interface UpdateUserProfileData {
74
+ uiapi: {
75
+ UserUpdate: { Record: Record<string, unknown> | null } | null;
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Extensible user-profile fetching and updating via UI API GraphQL — the
81
+ * Angular port of the React `userProfileApi.ts` module.
82
+ *
83
+ * Uses the base app's `DataClient` (which centralizes GraphQL error handling
84
+ * and routes mutations vs queries), matching the object-search feature's
85
+ * data-access idiom. Responses are flattened via `flattenGraphQLRecord` for
86
+ * straightforward form binding.
87
+ */
88
+ @Injectable({ providedIn: "root" })
89
+ export class UserProfileService {
90
+ private readonly client = inject(DataClient);
91
+
92
+ /**
93
+ * Fetches the user profile via GraphQL and returns a flattened record.
94
+ * @param userId - The Salesforce User Id.
95
+ * @param fields - GraphQL field selection (defaults to the full profile).
96
+ */
97
+ async fetchUserProfile<T>(userId: string, fields: string = USER_PROFILE_FIELDS_FULL): Promise<T> {
98
+ const data = await this.client.execute<GetUserProfileData, { userId: string }>(
99
+ getUserProfileQuery(fields),
100
+ { userId },
101
+ );
102
+ return flattenGraphQLRecord<T>(data.uiapi?.query?.User?.edges?.[0]?.node);
103
+ }
104
+
105
+ /**
106
+ * Fetches the user's associated contact record ID via GraphQL and returns a
107
+ * flattened record.
108
+ * @param userId - The Salesforce User Id.
109
+ */
110
+ async fetchUserContact<T>(userId: string): Promise<T> {
111
+ return this.fetchUserProfile<T>(userId, USER_CONTACT_FIELDS);
112
+ }
113
+
114
+ /**
115
+ * Updates the user profile via GraphQL and returns the flattened updated record.
116
+ * @param userId - The Salesforce User Id.
117
+ * @param values - The field values to update.
118
+ */
119
+ async updateUserProfile<T>(userId: string, values: Record<string, unknown>): Promise<T> {
120
+ const data = await this.client.execute<UpdateUserProfileData, { input: unknown }>(
121
+ getUserProfileMutation(USER_PROFILE_FIELDS_FULL),
122
+ { input: { Id: userId, User: { ...values } } },
123
+ );
124
+ return flattenGraphQLRecord<T>(data.uiapi?.UserUpdate?.Record);
125
+ }
126
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
7
+ import { provideRouter } from '@angular/router';
8
+ import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
9
+ import { provideNativeDateAdapter } from '@angular/material/core';
10
+
11
+ import { routes } from './app.routes';
12
+
13
+ export const appConfig: ApplicationConfig = {
14
+ providers: [
15
+ provideBrowserGlobalErrorListeners(),
16
+ provideRouter(routes),
17
+ provideAnimationsAsync(),
18
+ // Enables mat-datepicker (used by the object-search Date / DateRange
19
+ // filters) with the browser's native Date, avoiding a moment/luxon dep.
20
+ provideNativeDateAdapter(),
21
+ ],
22
+ };
@@ -0,0 +1,77 @@
1
+ import { Routes } from '@angular/router';
2
+ import { NotFoundComponent } from './pages/not-found/not-found';
3
+ import { authGuard } from "./features/authentication/auth/auth.guard";
4
+ import { LoginPageComponent } from "./pages/login/login-page";
5
+ import { RegisterPageComponent } from "./pages/register/register-page";
6
+ import { ForgotPasswordPageComponent } from "./pages/forgot-password/forgot-password-page";
7
+ import { ResetPasswordPageComponent } from "./pages/reset-password/reset-password-page";
8
+ import { ProfilePageComponent } from "./pages/profile/profile-page";
9
+ import { ChangePasswordPageComponent } from "./pages/change-password/change-password-page";
10
+ import { AppLayoutComponent } from "./components/layout/app-layout/app-layout";
11
+ import { HomePageComponent } from "./pages/home/home-page";
12
+ import { AccountSearchPageComponent } from "./pages/account-search/account-search-page";
13
+ import { AccountDetailPageComponent } from "./pages/account-detail/account-detail-page";
14
+
15
+ export const routes: Routes = [
16
+ {
17
+ path: "",
18
+ component: AppLayoutComponent,
19
+ children: [
20
+ {
21
+ path: "",
22
+ component: HomePageComponent,
23
+ data: { showInNavigation: true, label: "Home" }
24
+ },
25
+ {
26
+ path: "login",
27
+ component: LoginPageComponent,
28
+ title: "Login | MyApp",
29
+ data: { showInNavigation: false, label: "Login" }
30
+ },
31
+ {
32
+ path: "register",
33
+ component: RegisterPageComponent,
34
+ title: "Create Account | MyApp",
35
+ data: { showInNavigation: false }
36
+ },
37
+ {
38
+ path: "forgot-password",
39
+ component: ForgotPasswordPageComponent,
40
+ title: "Recover Password | MyApp",
41
+ data: { showInNavigation: false }
42
+ },
43
+ {
44
+ path: "reset-password",
45
+ component: ResetPasswordPageComponent,
46
+ title: "Reset Password | MyApp",
47
+ data: { showInNavigation: false }
48
+ },
49
+ {
50
+ path: "profile",
51
+ component: ProfilePageComponent,
52
+ canActivate: [authGuard],
53
+ title: "My Profile | MyApp",
54
+ data: { showInNavigation: false, label: "Profile" }
55
+ },
56
+ {
57
+ path: "change-password",
58
+ component: ChangePasswordPageComponent,
59
+ canActivate: [authGuard],
60
+ title: "Change Password | MyApp",
61
+ data: { showInNavigation: false }
62
+ },
63
+ {
64
+ path: "accounts/:recordId",
65
+ component: AccountDetailPageComponent
66
+ },
67
+ {
68
+ path: "accounts",
69
+ component: AccountSearchPageComponent
70
+ },
71
+ {
72
+ path: '**',
73
+ component: NotFoundComponent
74
+ }
75
+ ]
76
+ }
77
+ ];
@@ -0,0 +1,18 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { provideRouter } from '@angular/router';
3
+ import { App } from './app';
4
+
5
+ describe('App', () => {
6
+ beforeEach(async () => {
7
+ await TestBed.configureTestingModule({
8
+ imports: [App],
9
+ providers: [provideRouter([])],
10
+ }).compileComponents();
11
+ });
12
+
13
+ it('should create the app', () => {
14
+ const fixture = TestBed.createComponent(App);
15
+ const app = fixture.componentInstance;
16
+ expect(app).toBeTruthy();
17
+ });
18
+ });
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
7
+ import { RouterOutlet } from '@angular/router';
8
+
9
+ @Component({
10
+ selector: 'app-root',
11
+ changeDetection: ChangeDetectionStrategy.OnPush,
12
+ imports: [RouterOutlet],
13
+ templateUrl: './app.html',
14
+ })
15
+ export class App {}
@@ -0,0 +1,53 @@
1
+ <nav class="bg-white border-b border-gray-200">
2
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
3
+ <div class="flex justify-between items-center h-16">
4
+ <a routerLink="/" class="text-xl font-semibold text-gray-900"> Angular App </a>
5
+ <div class="flex items-center gap-2">
6
+ <app-auth-menu />
7
+ <button
8
+ (click)="toggleMenu()"
9
+ class="p-2 rounded-md text-gray-700 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500"
10
+ aria-label="Toggle menu"
11
+ [attr.aria-expanded]="isOpen()"
12
+ >
13
+ <div class="w-6 h-6 flex flex-col justify-center space-y-1.5">
14
+ <span
15
+ class="block h-0.5 w-6 bg-current transition-all"
16
+ [class.rotate-45]="isOpen()"
17
+ [class.translate-y-2]="isOpen()"
18
+ ></span>
19
+ <span
20
+ class="block h-0.5 w-6 bg-current transition-all"
21
+ [class.opacity-0]="isOpen()"
22
+ ></span>
23
+ <span
24
+ class="block h-0.5 w-6 bg-current transition-all"
25
+ [class.-rotate-45]="isOpen()"
26
+ [class.-translate-y-2]="isOpen()"
27
+ ></span>
28
+ </div>
29
+ </button>
30
+ </div>
31
+ </div>
32
+ @if (isOpen()) {
33
+ <div class="pb-4">
34
+ <ul class="flex flex-col space-y-2 list-none">
35
+ @for (item of navigationItems(); track item.path) {
36
+ <li>
37
+ <a
38
+ [routerLink]="item.path"
39
+ routerLinkActive="bg-blue-100 text-blue-700"
40
+ [routerLinkActiveOptions]="{ exact: true }"
41
+ (click)="closeMenu()"
42
+ class="block px-3 py-2 rounded-md text-sm font-medium transition-colors text-gray-700 hover:bg-gray-100"
43
+ >
44
+ {{ item.label }}
45
+ </a>
46
+ </li>
47
+ }
48
+ </ul>
49
+ </div>
50
+ }
51
+ </div>
52
+ </nav>
53
+ <router-outlet />
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import { Component } from "@angular/core";
7
+ import { TestBed } from "@angular/core/testing";
8
+ import { provideRouter } from "@angular/router";
9
+ import { AppLayoutComponent } from "./app-layout";
10
+ import { AuthMenuComponent } from "../../../features/authentication/menu/auth-menu/auth-menu";
11
+
12
+ // Stub the auth-menu so this layout test stays hermetic: the real
13
+ // `app-auth-menu` boots AuthService.checkAuth() (network + Cache API) on render,
14
+ // which is out of scope here and unavailable in the unit-test environment.
15
+ @Component({ selector: "app-auth-menu", template: "" })
16
+ class StubAuthMenuComponent {}
17
+
18
+ describe("AppLayoutComponent", () => {
19
+ beforeEach(async () => {
20
+ TestBed.configureTestingModule({
21
+ imports: [AppLayoutComponent],
22
+ providers: [
23
+ provideRouter([
24
+ {
25
+ path: "",
26
+ children: [
27
+ {
28
+ path: "accounts",
29
+ component: AppLayoutComponent,
30
+ data: { showInNavigation: true, label: "Accounts" },
31
+ },
32
+ ],
33
+ },
34
+ ]),
35
+ ],
36
+ });
37
+ TestBed.overrideComponent(AppLayoutComponent, {
38
+ remove: { imports: [AuthMenuComponent] },
39
+ add: { imports: [StubAuthMenuComponent] },
40
+ });
41
+ await TestBed.compileComponents();
42
+ });
43
+
44
+ it("should create the component", () => {
45
+ const fixture = TestBed.createComponent(AppLayoutComponent);
46
+ expect(fixture.componentInstance).toBeTruthy();
47
+ });
48
+
49
+ it("should toggle menu", () => {
50
+ const component = TestBed.createComponent(AppLayoutComponent).componentInstance;
51
+ expect(component.isOpen()).toBe(false);
52
+ component.toggleMenu();
53
+ expect(component.isOpen()).toBe(true);
54
+ component.toggleMenu();
55
+ expect(component.isOpen()).toBe(false);
56
+ });
57
+
58
+ it("should close menu", () => {
59
+ const component = TestBed.createComponent(AppLayoutComponent).componentInstance;
60
+ component.toggleMenu();
61
+ expect(component.isOpen()).toBe(true);
62
+ component.closeMenu();
63
+ expect(component.isOpen()).toBe(false);
64
+ });
65
+
66
+ it("should derive navigation items from the router config", () => {
67
+ const component = TestBed.createComponent(AppLayoutComponent).componentInstance;
68
+ const items = component.navigationItems();
69
+ expect(items.some((i) => i.path === "/accounts" && i.label === "Accounts")).toBe(true);
70
+ });
71
+
72
+ it("should render nav element", async () => {
73
+ const fixture = TestBed.createComponent(AppLayoutComponent);
74
+ await fixture.whenStable();
75
+ const compiled = fixture.nativeElement as HTMLElement;
76
+ expect(compiled.querySelector("nav")).toBeTruthy();
77
+ });
78
+
79
+ it("should set aria-expanded on toggle button", async () => {
80
+ const fixture = TestBed.createComponent(AppLayoutComponent);
81
+ await fixture.whenStable();
82
+ const button = (fixture.nativeElement as HTMLElement).querySelector("button");
83
+ expect(button?.getAttribute("aria-expanded")).toBe("false");
84
+
85
+ fixture.componentInstance.toggleMenu();
86
+ fixture.detectChanges();
87
+ expect(button?.getAttribute("aria-expanded")).toBe("true");
88
+ });
89
+ });