@salesforce/templates 66.11.0 → 66.12.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 (438) hide show
  1. package/lib/generators/projectGenerator.js +4 -1
  2. package/lib/generators/projectGenerator.js.map +1 -1
  3. package/lib/templates/project/angularextapp/.forceignore +15 -0
  4. package/lib/templates/project/angularextapp/.husky/pre-commit +4 -0
  5. package/lib/templates/project/angularextapp/.prettierignore +11 -0
  6. package/lib/templates/project/angularextapp/.prettierrc +17 -0
  7. package/lib/templates/project/angularextapp/CHANGELOG.md +4086 -0
  8. package/lib/templates/project/angularextapp/README.md +77 -0
  9. package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/angularextapp1.digitalExperience-meta.xml +11 -0
  10. package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/sfdc_cms__site/angularextapp1/_meta.json +5 -0
  11. package/lib/templates/project/angularextapp/_p_/_m_/_d_/_s_/angularextapp1/sfdc_cms__site/angularextapp1/content.json +10 -0
  12. package/lib/templates/project/angularextapp/_p_/_m_/_dc_/angularextapp1.digitalExperienceConfig-meta.xml +8 -0
  13. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
  14. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.postcssrc.json +5 -0
  15. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.prettierignore +8 -0
  16. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/.prettierrc +12 -0
  17. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/CHANGELOG.md +4 -0
  18. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/README.md +85 -0
  19. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +101 -0
  20. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angularextapp.uibundle-meta.xml +8 -0
  21. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +15 -0
  22. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/esbuild/api-version.mjs +17 -0
  23. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +60 -0
  24. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/middleware/html.mjs +3 -0
  25. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/middleware/proxy.mjs +12 -0
  26. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +13600 -0
  27. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +56 -0
  28. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/playwright.config.ts +25 -0
  29. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/public/favicon.ico +0 -0
  30. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +30 -0
  31. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/account-search.service.ts +196 -0
  32. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountIndustries.ts +26 -0
  33. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountTypes.ts +26 -0
  34. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/getAccountDetail.ts +128 -0
  35. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/account/searchAccounts.ts +58 -0
  36. package/lib/templates/{uiBundles/angularbasic/src/app/api/graphql-client.service.spec.ts → project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts} +36 -6
  37. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.ts +74 -0
  38. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/api/user-profile.service.ts +126 -0
  39. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.config.ts +22 -0
  40. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.html +1 -0
  41. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.routes.ts +77 -0
  42. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.spec.ts +18 -0
  43. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/app.ts +15 -0
  44. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.html +53 -0
  45. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.spec.ts +89 -0
  46. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.ts +81 -0
  47. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/_field-size.scss +42 -0
  48. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.html +31 -0
  49. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.ts +53 -0
  50. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.html +18 -0
  51. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.scss +112 -0
  52. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.ts +57 -0
  53. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.scss +34 -0
  54. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.ts +110 -0
  55. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.html +10 -0
  56. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.ts +26 -0
  57. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.html +25 -0
  58. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.scss +36 -0
  59. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.ts +41 -0
  60. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.html +34 -0
  61. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.scss +33 -0
  62. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.ts +66 -0
  63. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.html +37 -0
  64. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.ts +55 -0
  65. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.html +21 -0
  66. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.ts +36 -0
  67. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/field-size.ts +8 -0
  68. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.html +19 -0
  69. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.scss +35 -0
  70. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.ts +36 -0
  71. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.html +3 -0
  72. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.ts +17 -0
  73. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.html +10 -0
  74. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.ts +37 -0
  75. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.html +41 -0
  76. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.ts +40 -0
  77. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.html +24 -0
  78. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.scss +35 -0
  79. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts +72 -0
  80. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.html +1 -0
  81. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.scss +23 -0
  82. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.ts +56 -0
  83. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.html +1 -0
  84. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.scss +28 -0
  85. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.ts +24 -0
  86. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts +35 -0
  87. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth/auth.guard.ts +50 -0
  88. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth/auth.service.ts +126 -0
  89. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-form/auth-form.html +34 -0
  90. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-form/auth-form.ts +94 -0
  91. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-layout/auth-layout.html +2 -0
  92. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/auth-layout/auth-layout.ts +30 -0
  93. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/card-layout/card-layout.html +16 -0
  94. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/card-layout/card-layout.ts +40 -0
  95. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/config/authentication.config.ts +75 -0
  96. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/footer-link/footer-link.html +9 -0
  97. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/footer-link/footer-link.ts +26 -0
  98. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/menu/auth-menu/auth-menu.html +26 -0
  99. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/menu/auth-menu/auth-menu.ts +46 -0
  100. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/reactive-form-page.base.ts +50 -0
  101. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/session/session.html +55 -0
  102. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/session/session.ts +205 -0
  103. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/status-alert/status-alert.html +5 -0
  104. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/status-alert/status-alert.ts +52 -0
  105. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.html +5 -0
  106. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.scss +17 -0
  107. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/submit-button/submit-button.ts +35 -0
  108. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/auth-helpers.ts +68 -0
  109. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/auth-validators.ts +72 -0
  110. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/helpers.ts +85 -0
  111. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-time-servlet.ts +130 -0
  112. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-timeout.config.ts +83 -0
  113. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/authentication/utils/session-timeout.service.ts +201 -0
  114. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.html +54 -0
  115. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.ts +40 -0
  116. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.html +23 -0
  117. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.ts +78 -0
  118. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.html +18 -0
  119. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.ts +137 -0
  120. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.html +11 -0
  121. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.ts +69 -0
  122. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.html +11 -0
  123. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.ts +36 -0
  124. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.html +10 -0
  125. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
  126. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
  127. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.ts +146 -0
  128. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.html +8 -0
  129. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.ts +82 -0
  130. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.html +12 -0
  131. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.ts +65 -0
  132. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.html +12 -0
  133. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.ts +90 -0
  134. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/object-search-state.service.ts +232 -0
  135. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.html +8 -0
  136. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.ts +61 -0
  137. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.html +59 -0
  138. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.ts +108 -0
  139. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.html +50 -0
  140. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.ts +72 -0
  141. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/debounce.ts +31 -0
  142. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/field-utils.ts +54 -0
  143. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/filter-utils.ts +354 -0
  144. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/index.ts +12 -0
  145. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/sort-utils.ts +46 -0
  146. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.html +164 -0
  147. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.scss +7 -0
  148. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.ts +196 -0
  149. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.html +111 -0
  150. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.ts +217 -0
  151. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/change-password/change-password-page.html +68 -0
  152. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/change-password/change-password-page.ts +82 -0
  153. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/forgot-password/forgot-password-page.html +35 -0
  154. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/forgot-password/forgot-password-page.ts +87 -0
  155. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.html +18 -0
  156. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.ts +47 -0
  157. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.html +6 -0
  158. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.spec.ts +23 -0
  159. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.ts +13 -0
  160. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/login/login-page.html +47 -0
  161. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/login/login-page.ts +89 -0
  162. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.html +12 -0
  163. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.spec.ts +33 -0
  164. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.ts +15 -0
  165. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/profile/profile-page.html +116 -0
  166. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/profile/profile-page.ts +194 -0
  167. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/register/register-page.html +80 -0
  168. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/register/register-page.ts +93 -0
  169. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/reset-password/reset-password-page.html +60 -0
  170. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/pages/reset-password/reset-password-page.ts +96 -0
  171. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/app/utils/async-data.ts +99 -0
  172. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/index.html +14 -0
  173. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/main.ts +5 -0
  174. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/styles.scss +170 -0
  175. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/theme.scss +39 -0
  176. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/src/types/sf-globals.d.ts +9 -0
  177. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.app.json +11 -0
  178. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.json +33 -0
  179. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/tsconfig.spec.json +10 -0
  180. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
  181. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleAuthUtils.cls +68 -0
  182. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleAuthUtils.cls-meta.xml +5 -0
  183. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleChangePassword.cls +77 -0
  184. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleChangePassword.cls-meta.xml +5 -0
  185. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleForgotPassword.cls +71 -0
  186. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleForgotPassword.cls-meta.xml +5 -0
  187. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleLogin.cls +105 -0
  188. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleLogin.cls-meta.xml +5 -0
  189. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleRegistration.cls +162 -0
  190. package/lib/templates/project/angularextapp/_p_/_m_/classes/UIBundleRegistration.cls-meta.xml +5 -0
  191. package/lib/templates/project/angularextapp/_p_/_m_/networks/angularextapp.network-meta.xml +60 -0
  192. package/lib/templates/project/angularextapp/_p_/_m_/package.xml +24 -0
  193. package/lib/templates/project/angularextapp/_p_/_m_/permissionsets/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +9 -0
  194. package/lib/templates/project/angularextapp/_p_/_m_/sites/angularextapp.site-meta.xml +31 -0
  195. package/lib/templates/project/angularextapp/config/project-scratch-def.json +13 -0
  196. package/lib/templates/project/angularextapp/eslint.config.js +7 -0
  197. package/lib/templates/project/angularextapp/jest.config.js +6 -0
  198. package/lib/templates/project/angularextapp/package.json +46 -0
  199. package/lib/templates/project/angularextapp/scripts/apex/hello.apex +10 -0
  200. package/lib/templates/project/angularextapp/scripts/gitignore-templates.json +4 -0
  201. package/lib/templates/project/angularextapp/scripts/graphql-search.sh +191 -0
  202. package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +103 -0
  203. package/lib/templates/project/angularextapp/scripts/org-setup-dev.mjs +87 -0
  204. package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +369 -0
  205. package/lib/templates/project/angularextapp/scripts/org-setup-xml.mjs +182 -0
  206. package/lib/templates/project/angularextapp/scripts/org-setup.config.json +9 -0
  207. package/lib/templates/project/angularextapp/scripts/org-setup.mjs +1702 -0
  208. package/lib/templates/project/angularextapp/scripts/sf-project-setup.mjs +103 -0
  209. package/lib/templates/project/angularextapp/scripts/soql/account.soql +6 -0
  210. package/lib/templates/project/angularextapp/scripts/validate-org-setup-config.mjs +38 -0
  211. package/lib/templates/project/angularextapp/sfdx-project.json +12 -0
  212. package/lib/templates/project/angularintapp/.forceignore +15 -0
  213. package/lib/templates/project/angularintapp/.husky/pre-commit +4 -0
  214. package/lib/templates/project/angularintapp/.prettierignore +11 -0
  215. package/lib/templates/project/angularintapp/.prettierrc +17 -0
  216. package/lib/templates/project/angularintapp/CHANGELOG.md +4086 -0
  217. package/lib/templates/project/angularintapp/README.md +77 -0
  218. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
  219. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.postcssrc.json +5 -0
  220. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.prettierignore +8 -0
  221. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/.prettierrc +12 -0
  222. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/CHANGELOG.md +4 -0
  223. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/README.md +85 -0
  224. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +101 -0
  225. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angularintapp.uibundle-meta.xml +8 -0
  226. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +15 -0
  227. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/esbuild/api-version.mjs +17 -0
  228. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +60 -0
  229. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/middleware/html.mjs +3 -0
  230. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/middleware/proxy.mjs +12 -0
  231. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +13619 -0
  232. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +57 -0
  233. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/playwright.config.ts +25 -0
  234. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/public/favicon.ico +0 -0
  235. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +30 -0
  236. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/account-search.service.ts +196 -0
  237. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountIndustries.ts +26 -0
  238. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/distinctAccountTypes.ts +26 -0
  239. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/getAccountDetail.ts +128 -0
  240. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/account/searchAccounts.ts +58 -0
  241. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.spec.ts +184 -0
  242. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/api/data-client.service.ts +74 -0
  243. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.config.ts +22 -0
  244. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.html +1 -0
  245. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.routes.ts +31 -0
  246. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.spec.ts +18 -0
  247. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/app.ts +15 -0
  248. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.html +52 -0
  249. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.spec.ts +90 -0
  250. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/layout/app-layout/app-layout.ts +67 -0
  251. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/_field-size.scss +42 -0
  252. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.html +31 -0
  253. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/alert/alert.ts +53 -0
  254. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.html +18 -0
  255. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.scss +112 -0
  256. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/button/button.ts +57 -0
  257. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.scss +34 -0
  258. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/card/card.ts +110 -0
  259. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.html +10 -0
  260. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/collapsible/collapsible.ts +26 -0
  261. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.html +25 -0
  262. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.scss +36 -0
  263. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-picker/date-picker.ts +41 -0
  264. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.html +34 -0
  265. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.scss +33 -0
  266. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/date-range-picker/date-range-picker.ts +66 -0
  267. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.html +37 -0
  268. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/dialog/dialog.ts +55 -0
  269. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.html +21 -0
  270. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field/field.ts +36 -0
  271. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/field-size.ts +8 -0
  272. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.html +19 -0
  273. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.scss +35 -0
  274. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/input/input.ts +36 -0
  275. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.html +3 -0
  276. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/label/label.ts +17 -0
  277. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.html +10 -0
  278. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/paginator/paginator.ts +37 -0
  279. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.html +41 -0
  280. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/popover/popover.ts +40 -0
  281. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.html +24 -0
  282. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.scss +35 -0
  283. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/select/select.ts +72 -0
  284. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.html +1 -0
  285. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.scss +23 -0
  286. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/separator/separator.ts +56 -0
  287. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.html +1 -0
  288. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.scss +28 -0
  289. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/skeleton/skeleton.ts +24 -0
  290. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/spinner/spinner.ts +35 -0
  291. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +177 -0
  292. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/conversation.html +3 -0
  293. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/conversation.ts +119 -0
  294. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.html +54 -0
  295. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/breadcrumb/breadcrumb.ts +40 -0
  296. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.html +23 -0
  297. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/active-filters.ts +78 -0
  298. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.html +18 -0
  299. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-filter.ts +137 -0
  300. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.html +11 -0
  301. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/date-range-filter.ts +69 -0
  302. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.html +11 -0
  303. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/filter-field-wrapper.ts +36 -0
  304. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.html +10 -0
  305. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
  306. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
  307. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/numeric-range-filter.ts +146 -0
  308. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.html +8 -0
  309. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/search-filter.ts +82 -0
  310. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.html +12 -0
  311. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/select-filter.ts +65 -0
  312. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.html +12 -0
  313. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/filters/text-filter.ts +90 -0
  314. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/object-search-state.service.ts +232 -0
  315. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.html +8 -0
  316. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/pagination/pagination.ts +61 -0
  317. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.html +59 -0
  318. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/search-bar/search-bar.ts +108 -0
  319. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.html +50 -0
  320. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/sort-control/sort-control.ts +72 -0
  321. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/debounce.ts +31 -0
  322. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/field-utils.ts +54 -0
  323. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/filter-utils.ts +354 -0
  324. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/index.ts +12 -0
  325. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/object-search/utils/sort-utils.ts +46 -0
  326. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.html +164 -0
  327. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.scss +7 -0
  328. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-detail/account-detail-page.ts +196 -0
  329. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.html +111 -0
  330. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/account-search/account-search-page.ts +217 -0
  331. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.html +18 -0
  332. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home-page.ts +47 -0
  333. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.html +6 -0
  334. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.spec.ts +23 -0
  335. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/home/home.ts +13 -0
  336. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.html +12 -0
  337. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.spec.ts +33 -0
  338. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/pages/not-found/not-found.ts +15 -0
  339. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/types/conversation.ts +55 -0
  340. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/types/globals.d.ts +13 -0
  341. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/utils/async-data.ts +99 -0
  342. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/index.html +14 -0
  343. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/index.ts +15 -0
  344. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/main.ts +5 -0
  345. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/styles.scss +170 -0
  346. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/theme.scss +39 -0
  347. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/types/sf-globals.d.ts +9 -0
  348. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.app.json +11 -0
  349. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.json +33 -0
  350. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/tsconfig.spec.json +10 -0
  351. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
  352. package/lib/templates/project/angularintapp/_p_/_m_/applications/angularintapp.app-meta.xml +17 -0
  353. package/lib/templates/project/angularintapp/_p_/_m_/permissionsets/angularintapp_Access.permissionset-meta.xml +13 -0
  354. package/lib/templates/project/angularintapp/config/project-scratch-def.json +13 -0
  355. package/lib/templates/project/angularintapp/eslint.config.js +7 -0
  356. package/lib/templates/project/angularintapp/jest.config.js +6 -0
  357. package/lib/templates/project/angularintapp/package.json +46 -0
  358. package/lib/templates/project/angularintapp/scripts/apex/hello.apex +10 -0
  359. package/lib/templates/project/angularintapp/scripts/gitignore-templates.json +4 -0
  360. package/lib/templates/project/angularintapp/scripts/graphql-search.sh +191 -0
  361. package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +103 -0
  362. package/lib/templates/project/angularintapp/scripts/org-setup-dev.mjs +87 -0
  363. package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +369 -0
  364. package/lib/templates/project/angularintapp/scripts/org-setup-xml.mjs +182 -0
  365. package/lib/templates/project/angularintapp/scripts/org-setup.config.json +9 -0
  366. package/lib/templates/project/angularintapp/scripts/org-setup.mjs +1702 -0
  367. package/lib/templates/project/angularintapp/scripts/sf-project-setup.mjs +103 -0
  368. package/lib/templates/project/angularintapp/scripts/soql/account.soql +6 -0
  369. package/lib/templates/project/angularintapp/scripts/validate-org-setup-config.mjs +38 -0
  370. package/lib/templates/project/angularintapp/sfdx-project.json +12 -0
  371. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +864 -807
  372. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +857 -800
  373. package/lib/templates/uiBundles/angularbasic/angular.json +11 -7
  374. package/lib/templates/uiBundles/angularbasic/eslint.config.js +4 -0
  375. package/lib/templates/uiBundles/angularbasic/package-lock.json +351 -319
  376. package/lib/templates/uiBundles/angularbasic/package.json +4 -0
  377. package/lib/templates/uiBundles/angularbasic/src/app/api/data-client.service.spec.ts +184 -0
  378. package/lib/templates/uiBundles/angularbasic/src/app/api/data-client.service.ts +74 -0
  379. package/lib/templates/uiBundles/angularbasic/src/app/app.config.ts +15 -1
  380. package/lib/templates/uiBundles/angularbasic/src/app/app.routes.ts +6 -1
  381. package/lib/templates/uiBundles/angularbasic/src/app/app.ts +7 -2
  382. package/lib/templates/uiBundles/angularbasic/src/app/{layout → components/layout/app-layout}/app-layout.component.html +2 -1
  383. package/lib/templates/uiBundles/angularbasic/src/app/{layout → components/layout/app-layout}/app-layout.component.ts +9 -3
  384. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/_field-size.scss +42 -0
  385. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/alert/alert.component.html +31 -0
  386. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/alert/alert.component.ts +53 -0
  387. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/button/button.component.html +18 -0
  388. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/button/button.component.scss +112 -0
  389. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/button/button.component.ts +57 -0
  390. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/card/card.component.scss +34 -0
  391. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/card/card.component.ts +110 -0
  392. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/collapsible/collapsible.component.html +10 -0
  393. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/collapsible/collapsible.component.ts +26 -0
  394. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-picker/date-picker.component.html +25 -0
  395. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-picker/date-picker.component.scss +36 -0
  396. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-picker/date-picker.component.ts +41 -0
  397. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-range-picker/date-range-picker.component.html +34 -0
  398. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-range-picker/date-range-picker.component.scss +33 -0
  399. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/date-range-picker/date-range-picker.component.ts +66 -0
  400. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/dialog/dialog.component.html +37 -0
  401. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/dialog/dialog.component.ts +55 -0
  402. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/field/field.component.html +21 -0
  403. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/field/field.component.ts +36 -0
  404. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/field-size.ts +8 -0
  405. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/input/input.component.html +19 -0
  406. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/input/input.component.scss +35 -0
  407. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/input/input.component.ts +36 -0
  408. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/label/label.component.html +3 -0
  409. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/label/label.component.ts +17 -0
  410. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/paginator/paginator.component.html +10 -0
  411. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/paginator/paginator.component.ts +37 -0
  412. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/popover/popover.component.html +41 -0
  413. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/popover/popover.component.ts +40 -0
  414. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/select/select.component.html +24 -0
  415. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/select/select.component.scss +35 -0
  416. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/select/select.component.ts +72 -0
  417. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/separator/separator.component.html +1 -0
  418. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/separator/separator.component.scss +23 -0
  419. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/separator/separator.component.ts +56 -0
  420. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/skeleton/skeleton.component.html +1 -0
  421. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/skeleton/skeleton.component.scss +28 -0
  422. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/skeleton/skeleton.component.ts +24 -0
  423. package/lib/templates/uiBundles/angularbasic/src/app/components/ui/spinner/spinner.component.ts +35 -0
  424. package/lib/templates/uiBundles/angularbasic/src/app/pages/home/home.component.ts +7 -1
  425. package/lib/templates/uiBundles/angularbasic/src/app/pages/not-found/not-found.component.ts +7 -1
  426. package/lib/templates/uiBundles/angularbasic/src/app/utils/async-data.ts +99 -0
  427. package/lib/templates/uiBundles/angularbasic/src/index.html +1 -0
  428. package/lib/templates/uiBundles/angularbasic/src/styles.scss +170 -0
  429. package/lib/templates/uiBundles/angularbasic/src/theme.scss +39 -0
  430. package/lib/templates/uiBundles/reactbasic/package-lock.json +857 -800
  431. package/lib/utils/types.d.ts +1 -1
  432. package/lib/utils/uiBundleTemplateUtils.js +10 -0
  433. package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
  434. package/package.json +5 -3
  435. package/lib/templates/uiBundles/angularbasic/src/app/api/graphql-client.service.ts +0 -48
  436. package/lib/templates/uiBundles/angularbasic/src/app/app.css +0 -0
  437. package/lib/templates/uiBundles/angularbasic/src/styles.css +0 -12
  438. /package/lib/templates/uiBundles/angularbasic/src/app/{layout → components/layout/app-layout}/app-layout.component.spec.ts +0 -0
@@ -0,0 +1,137 @@
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, computed, inject, input } from "@angular/core";
7
+ // Base-app UI wrappers, inherited (not recreated) by this feature. Post-compose
8
+ // they land at uiBundles/<target>/src/app/components/ui/{date-picker,select}/..., four
9
+ // levels up.
10
+ import { DatePickerComponent } from "../../../components/ui/date-picker/date-picker";
11
+ import {
12
+ SelectComponent,
13
+ type AppSelectOption,
14
+ } from "../../../components/ui/select/select";
15
+ import { ObjectSearchStateService } from "../object-search-state.service";
16
+ import type { FilterFieldConfig, FilterFieldType } from "../utils/filter-utils";
17
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
18
+
19
+ /**
20
+ * Single-date filter — operator select ("After" / "Before") plus a date
21
+ * picker. Emits a filter whose `value` is the operator (`'gt'` or `'lt'`) and
22
+ * whose date is placed in `min` (for `gt`) or `max` (for `lt`), matching the
23
+ * React reference and the `date` / `datetime` branch of `buildSingleFilter`.
24
+ *
25
+ * The `filterType` input toggles the emitted `type` between `'date'` and
26
+ * `'datetime'` (the latter adds start/end-of-day promotion in the filter
27
+ * builder).
28
+ */
29
+ type DateOperator = "gt" | "lt";
30
+
31
+ const OPERATOR_OPTIONS: readonly AppSelectOption[] = [
32
+ { value: "gt", label: "After" },
33
+ { value: "lt", label: "Before" },
34
+ ];
35
+
36
+ @Component({
37
+ selector: "app-date-filter",
38
+ changeDetection: ChangeDetectionStrategy.OnPush,
39
+ imports: [DatePickerComponent, SelectComponent, FilterFieldWrapperComponent],
40
+ templateUrl: "./date-filter.html",
41
+ })
42
+ export class DateFilterComponent {
43
+ private readonly state = inject(ObjectSearchStateService);
44
+
45
+ /** Field config: `field`, `label`, `helpText`, ... */
46
+ readonly config = input.required<FilterFieldConfig>();
47
+ /** Underlying filter type — `'date'` (default) or `'datetime'`. */
48
+ readonly filterType = input<FilterFieldType>("date");
49
+
50
+ protected readonly operatorOptions = OPERATOR_OPTIONS;
51
+
52
+ /** Active filter (if any) — the single source of truth for both fields. */
53
+ private readonly active = computed(() => this.state.filterFor(this.config().field));
54
+
55
+ /** Cap the picker at today when the field can't hold a future date. */
56
+ protected readonly maxDate = computed<Date | null>(() =>
57
+ this.config().disableFuture ? new Date() : null,
58
+ );
59
+
60
+ /**
61
+ * Selected operator. Defaults to `'gt'` when no filter is active, mirroring
62
+ * the React initial state (`min` present -> `gt`, else `lt`, but with no
63
+ * active filter React ended up on `lt`; we prefer `'gt'` as the safer
64
+ * "After a date" default when nothing is selected).
65
+ */
66
+ protected readonly operator = computed<DateOperator>(() => {
67
+ const a = this.active();
68
+ if (a?.value === "gt" || a?.value === "lt") return a.value;
69
+ if (a?.min) return "gt";
70
+ if (a?.max) return "lt";
71
+ return "gt";
72
+ });
73
+
74
+ /** Date picker value — parsed from either `min` (gt) or `max` (lt). */
75
+ protected readonly currentDate = computed<Date | null>(() => {
76
+ const a = this.active();
77
+ return toDate(a?.min ?? a?.max);
78
+ });
79
+
80
+ protected onOperatorChange(v: string): void {
81
+ const op = v === "lt" ? "lt" : "gt";
82
+ const date = this.currentDate();
83
+ // Only re-emit if we already had a date; otherwise wait until the user
84
+ // picks one (matches React `emitChange` gate on `currentDate`).
85
+ if (date) this.emit(op, date);
86
+ }
87
+
88
+ protected onDateChange(date: Date | null): void {
89
+ const cfg = this.config();
90
+ if (!date) {
91
+ this.state.removeFilter(cfg.field);
92
+ } else {
93
+ this.emit(this.operator(), date);
94
+ }
95
+ }
96
+
97
+ private emit(op: DateOperator, date: Date): void {
98
+ const cfg = this.config();
99
+ const dateStr = toDateString(date);
100
+ const isMin = op === "gt";
101
+ this.state.setFilter(cfg.field, {
102
+ field: cfg.field,
103
+ label: cfg.label,
104
+ type: this.filterType(),
105
+ value: op,
106
+ min: isMin ? dateStr : undefined,
107
+ max: isMin ? undefined : dateStr,
108
+ });
109
+ }
110
+ }
111
+
112
+ /** Parses `YYYY-MM-DD` (or any ISO date) into a `Date`, or `null` on failure. */
113
+ export function toDate(value: string | undefined): Date | null {
114
+ if (!value) return null;
115
+ // Interpret bare YYYY-MM-DD as a local-time date so the picker doesn't
116
+ // display "yesterday" in negative UTC offsets.
117
+ const parts = value.split("T")[0].split("-");
118
+ if (parts.length === 3) {
119
+ const [y, m, d] = parts.map((p) => Number(p));
120
+ const dt = new Date(y, m - 1, d);
121
+ return isNaN(dt.getTime()) ? null : dt;
122
+ }
123
+ const dt = new Date(value);
124
+ return isNaN(dt.getTime()) ? null : dt;
125
+ }
126
+
127
+ /** Formats a `Date` as `YYYY-MM-DD` in local time. */
128
+ export function toDateString(date: Date | null | undefined): string {
129
+ if (!date || isNaN(date.getTime())) return "";
130
+ const y = date.getFullYear();
131
+ // Guard against partially-typed years (e.g. `202` instead of `2026`), which
132
+ // would serialize to an invalid `202-07-09` and be rejected by the API.
133
+ if (y < 1000 || y > 9999) return "";
134
+ const m = String(date.getMonth() + 1).padStart(2, "0");
135
+ const d = String(date.getDate()).padStart(2, "0");
136
+ return `${y}-${m}-${d}`;
137
+ }
@@ -0,0 +1,11 @@
1
+ <app-filter-field-wrapper [label]="config().label" [helpText]="config().helpText">
2
+ <app-date-range-picker
3
+ class="w-full"
4
+ startPlaceholder="Start"
5
+ endPlaceholder="End"
6
+ [readonly]="true"
7
+ [max]="maxDate()"
8
+ [value]="range()"
9
+ (valueChange)="onRangeChange($event)"
10
+ />
11
+ </app-filter-field-wrapper>
@@ -0,0 +1,69 @@
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, computed, inject, input } from "@angular/core";
7
+ // Base-app UI wrapper, inherited (not recreated) by this feature. Post-compose
8
+ // it lands at uiBundles/<target>/src/app/components/ui/date-range-picker/..., three levels up.
9
+ import {
10
+ DateRange,
11
+ DateRangePickerComponent,
12
+ } from "../../../components/ui/date-range-picker/date-range-picker";
13
+ import { ObjectSearchStateService } from "../object-search-state.service";
14
+ import type { FilterFieldConfig, FilterFieldType } from "../utils/filter-utils";
15
+ import { toDate, toDateString } from "./date-filter";
16
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
17
+
18
+ /**
19
+ * Date range filter — a single two-ended range picker. Emits a `daterange`
20
+ * (or `datetimerange`) filter with `min` / `max` as `YYYY-MM-DD` strings; the
21
+ * filter builder wires each end into a `gte` / `lte` clause.
22
+ *
23
+ * Thin bridge over the base `app-date-range-picker` (Material's
24
+ * `mat-date-range-picker`): it maps the picker's `DateRange<Date>` value to and
25
+ * from the `min` / `max` string split the filter state stores.
26
+ */
27
+ @Component({
28
+ selector: "app-date-range-filter",
29
+ changeDetection: ChangeDetectionStrategy.OnPush,
30
+ imports: [DateRangePickerComponent, FilterFieldWrapperComponent],
31
+ templateUrl: "./date-range-filter.html",
32
+ })
33
+ export class DateRangeFilterComponent {
34
+ private readonly state = inject(ObjectSearchStateService);
35
+
36
+ /** Field config: `field`, `label`, `helpText`, ... */
37
+ readonly config = input.required<FilterFieldConfig>();
38
+ /** Underlying filter type — `'daterange'` (default) or `'datetimerange'`. */
39
+ readonly filterType = input<FilterFieldType>("daterange");
40
+
41
+ private readonly active = computed(() => this.state.filterFor(this.config().field));
42
+
43
+ /** The active filter's `min` / `max` strings surfaced as a picker range. */
44
+ protected readonly range = computed<DateRange<Date>>(
45
+ () => new DateRange(toDate(this.active()?.min), toDate(this.active()?.max)),
46
+ );
47
+
48
+ /** Cap the picker at today when the field can't hold a future date. */
49
+ protected readonly maxDate = computed<Date | null>(() =>
50
+ this.config().disableFuture ? new Date() : null,
51
+ );
52
+
53
+ protected onRangeChange(range: DateRange<Date> | null): void {
54
+ const cfg = this.config();
55
+ const from = range?.start ?? null;
56
+ const to = range?.end ?? null;
57
+ if (!from && !to) {
58
+ this.state.removeFilter(cfg.field);
59
+ return;
60
+ }
61
+ this.state.setFilter(cfg.field, {
62
+ field: cfg.field,
63
+ label: cfg.label,
64
+ type: this.filterType(),
65
+ min: toDateString(from),
66
+ max: toDateString(to),
67
+ });
68
+ }
69
+ }
@@ -0,0 +1,11 @@
1
+ <div class="space-y-1">
2
+ <app-label [for]="htmlFor()">{{ label() }}</app-label>
3
+ <ng-content />
4
+ <div class="min-h-4">
5
+ @if (error(); as err) {
6
+ <p class="text-xs text-red-600" role="alert">{{ err }}</p>
7
+ } @else if (helpText(); as help) {
8
+ <p class="text-xs text-gray-500">{{ help }}</p>
9
+ }
10
+ </div>
11
+ </div>
@@ -0,0 +1,36 @@
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, input } from "@angular/core";
7
+ // Base-app UI wrapper, inherited (not recreated) by this feature. Post-compose
8
+ // it lands at uiBundles/<target>/src/app/components/ui/label/..., three levels up from this
9
+ // filter folder (app/object-search/filters/ -> app/components/ui/).
10
+ import { LabelComponent } from "../../../components/ui/label/label";
11
+
12
+ /**
13
+ * Standard label + control + help/error scaffold shared by every filter
14
+ * component (the Angular analogue of the React `FilterFieldWrapper`).
15
+ *
16
+ * The control itself is content-projected so each filter can supply the
17
+ * primitive that fits its data type (input, select, popover, date picker, ...)
18
+ * while the wrapper keeps the layout, label, and error/help affordances
19
+ * consistent across the search page.
20
+ */
21
+ @Component({
22
+ selector: "app-filter-field-wrapper",
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ imports: [LabelComponent],
25
+ templateUrl: "./filter-field-wrapper.html",
26
+ })
27
+ export class FilterFieldWrapperComponent {
28
+ /** Visible field label rendered above the control. */
29
+ readonly label = input.required<string>();
30
+ /** Optional `for` attribute forwarded to the underlying `<label>`. */
31
+ readonly htmlFor = input<string | null>(null);
32
+ /** Advisory copy rendered below the control when there is no error. */
33
+ readonly helpText = input<string | undefined>(undefined);
34
+ /** Validation message; when set, replaces the help text. */
35
+ readonly error = input<string | undefined>(undefined);
36
+ }
@@ -0,0 +1,10 @@
1
+ <app-filter-field-wrapper [label]="config().label" [helpText]="config().helpText">
2
+ <app-select
3
+ multiple
4
+ [size]="size()"
5
+ [options]="config().options ?? []"
6
+ [placeholder]="placeholder()"
7
+ [values]="selected()"
8
+ (valuesChange)="onSelectionChange($event)"
9
+ />
10
+ </app-filter-field-wrapper>
@@ -0,0 +1,58 @@
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, computed, inject, input } from "@angular/core";
7
+ import type { AppFieldSize } from "../../../components/ui/field-size";
8
+ import { SelectComponent } from "../../../components/ui/select/select";
9
+ import { ObjectSearchStateService } from "../object-search-state.service";
10
+ import type { FilterFieldConfig } from "../utils/filter-utils";
11
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
12
+
13
+ /**
14
+ * Multi-select picklist filter. All presentation (checkbox options, trigger
15
+ * summary, height) lives in `app-select multiple`; this component only bridges
16
+ * the UI's `string[]` selection to the object-search state, serializing it into
17
+ * the comma-joined string the `type: 'multipicklist'` contract expects
18
+ * (`buildSingleFilter` maps that to `{ eq }` for one value, `{ in: [...] }` for
19
+ * many).
20
+ */
21
+ @Component({
22
+ selector: "app-multi-select-filter",
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ imports: [SelectComponent, FilterFieldWrapperComponent],
25
+ templateUrl: "./multi-select-filter.html",
26
+ })
27
+ export class MultiSelectFilterComponent {
28
+ private readonly state = inject(ObjectSearchStateService);
29
+
30
+ /** Field config: `field`, `label`, `options`, `helpText`, ... */
31
+ readonly config = input.required<FilterFieldConfig>();
32
+
33
+ /** Field height: `sm` = 24px, `default` = 32px, `lg` = 40px. */
34
+ readonly size = input<AppFieldSize>("default");
35
+
36
+ /** Currently selected option values (parsed back from the comma-joined string). */
37
+ protected readonly selected = computed<string[]>(() => {
38
+ const raw = this.state.filterFor(this.config().field)?.value;
39
+ return raw ? raw.split(",") : [];
40
+ });
41
+
42
+ /** Placeholder shown on the trigger when nothing is selected. */
43
+ protected readonly placeholder = computed(() => `Select ${this.config().label.toLowerCase()}`);
44
+
45
+ protected onSelectionChange(next: readonly string[]): void {
46
+ const cfg = this.config();
47
+ if (next.length === 0) {
48
+ this.state.removeFilter(cfg.field);
49
+ } else {
50
+ this.state.setFilter(cfg.field, {
51
+ field: cfg.field,
52
+ label: cfg.label,
53
+ type: "multipicklist",
54
+ value: next.join(","),
55
+ });
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,22 @@
1
+ <app-filter-field-wrapper
2
+ [label]="config().label"
3
+ [helpText]="config().helpText"
4
+ [error]="errorMessage()"
5
+ >
6
+ <div class="flex gap-2">
7
+ <app-input
8
+ class="flex-1"
9
+ type="number"
10
+ placeholder="Min"
11
+ [value]="localMin()"
12
+ (valueChange)="onMinChange($event)"
13
+ />
14
+ <app-input
15
+ class="flex-1"
16
+ type="number"
17
+ placeholder="Max"
18
+ [value]="localMax()"
19
+ (valueChange)="onMaxChange($event)"
20
+ />
21
+ </div>
22
+ </app-filter-field-wrapper>
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import {
7
+ ChangeDetectionStrategy,
8
+ Component,
9
+ DestroyRef,
10
+ computed,
11
+ effect,
12
+ inject,
13
+ input,
14
+ signal,
15
+ } from "@angular/core";
16
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
17
+ import { Subject } from "rxjs";
18
+ import { debounceTime } from "rxjs/operators";
19
+ import { MatInputModule } from "@angular/material/input";
20
+ import { MatFormFieldModule } from "@angular/material/form-field";
21
+ import { FormsModule } from "@angular/forms";
22
+ // Base-app UI wrapper, inherited (not recreated) by this feature. Post-compose
23
+ // it lands at uiBundles/<target>/src/app/components/ui/input/..., three levels up.
24
+ import { InputComponent } from "../../../components/ui/input/input";
25
+ import { ObjectSearchStateService } from "../object-search-state.service";
26
+ import { FILTER_DEBOUNCE_MS } from "../utils/debounce";
27
+ import type { FilterFieldConfig } from "../utils/filter-utils";
28
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
29
+
30
+ /**
31
+ * Numeric range filter — paired `min` / `max` inputs whose committed values are
32
+ * written as strings on a `type: 'numeric'` filter (numeric coercion happens
33
+ * in `buildSingleFilter`).
34
+ *
35
+ * Local signals drive the inputs immediately; a trailing debounce commits the
36
+ * pair, but only when the range is self-consistent (`min <= max`) and within
37
+ * `boundMin` / `boundMax` if provided — an inverted or out-of-bounds pair
38
+ * shows the same inline error the React reference renders and skips the write.
39
+ */
40
+ @Component({
41
+ selector: "app-numeric-range-filter",
42
+ changeDetection: ChangeDetectionStrategy.OnPush,
43
+ imports: [
44
+ InputComponent,
45
+ FilterFieldWrapperComponent,
46
+ FormsModule,
47
+ MatFormFieldModule,
48
+ MatInputModule,
49
+ ],
50
+ templateUrl: "./numeric-range-filter.html",
51
+ })
52
+ export class NumericRangeFilterComponent {
53
+ private readonly state = inject(ObjectSearchStateService);
54
+ private readonly destroyRef = inject(DestroyRef);
55
+
56
+ /** Field config: `field`, `label`, `helpText`, ... */
57
+ readonly config = input.required<FilterFieldConfig>();
58
+ /** Optional lower bound accepted by the field (used for validation only). */
59
+ readonly boundMin = input<number | undefined>(undefined);
60
+ /** Optional upper bound accepted by the field (used for validation only). */
61
+ readonly boundMax = input<number | undefined>(undefined);
62
+
63
+ protected readonly localMin = signal<string>("");
64
+ protected readonly localMax = signal<string>("");
65
+
66
+ private readonly commit$ = new Subject<{ min: string; max: string }>();
67
+
68
+ constructor() {
69
+ this.commit$
70
+ .pipe(debounceTime(FILTER_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
71
+ .subscribe(({ min, max }) => this.commit(min, max));
72
+
73
+ // Sync local inputs from shared state (URL restore / reset-all).
74
+ effect(() => {
75
+ const cfg = this.config();
76
+ const active = this.state.filterFor(cfg.field);
77
+ this.localMin.set(active?.min ?? "");
78
+ this.localMax.set(active?.max ?? "");
79
+ });
80
+ }
81
+
82
+ protected readonly minOutOfBounds = computed(() => this.isOutOfBounds(this.localMin()));
83
+ protected readonly maxOutOfBounds = computed(() => this.isOutOfBounds(this.localMax()));
84
+ protected readonly isRangeInverted = computed(() => {
85
+ const lo = this.localMin();
86
+ const hi = this.localMax();
87
+ return lo !== "" && hi !== "" && Number(lo) > Number(hi);
88
+ });
89
+ protected readonly hasError = computed(
90
+ () => this.minOutOfBounds() || this.maxOutOfBounds() || this.isRangeInverted(),
91
+ );
92
+
93
+ protected readonly errorMessage = computed<string | undefined>(() => {
94
+ if (this.isRangeInverted()) return "Min must not exceed max";
95
+ if (!this.minOutOfBounds() && !this.maxOutOfBounds()) return undefined;
96
+ const lo = this.boundMin();
97
+ const hi = this.boundMax();
98
+ if (lo != null && hi != null) return `Value must be between ${lo}–${hi}`;
99
+ if (lo != null) return `Value must be ${lo} or more`;
100
+ if (hi != null) return `Value must be ${hi} or less`;
101
+ return undefined;
102
+ });
103
+
104
+ protected onMinChange(v: string): void {
105
+ this.localMin.set(v);
106
+ this.commit$.next({ min: v, max: this.localMax() });
107
+ }
108
+
109
+ protected onMaxChange(v: string): void {
110
+ this.localMax.set(v);
111
+ this.commit$.next({ min: this.localMin(), max: v });
112
+ }
113
+
114
+ private isOutOfBounds(v: string): boolean {
115
+ if (v === "") return false;
116
+ const n = Number(v);
117
+ const lo = this.boundMin();
118
+ const hi = this.boundMax();
119
+ return (lo != null && n < lo) || (hi != null && n > hi);
120
+ }
121
+
122
+ private commit(min: string, max: string): void {
123
+ const cfg = this.config();
124
+ if (!min && !max) {
125
+ this.state.removeFilter(cfg.field);
126
+ return;
127
+ }
128
+ const minNum = min !== "" ? Number(min) : null;
129
+ const maxNum = max !== "" ? Number(max) : null;
130
+ // Skip writes that would produce an inverted or out-of-bounds clause;
131
+ // the UI keeps the input contents so the user can correct in place.
132
+ if (minNum != null && maxNum != null && minNum > maxNum) return;
133
+ const lo = this.boundMin();
134
+ const hi = this.boundMax();
135
+ if (minNum != null && ((lo != null && minNum < lo) || (hi != null && minNum > hi))) return;
136
+ if (maxNum != null && ((lo != null && maxNum < lo) || (hi != null && maxNum > hi))) return;
137
+
138
+ this.state.setFilter(cfg.field, {
139
+ field: cfg.field,
140
+ label: cfg.label,
141
+ type: "numeric",
142
+ min,
143
+ max,
144
+ });
145
+ }
146
+ }
@@ -0,0 +1,8 @@
1
+ <app-filter-field-wrapper [label]="config().label" [htmlFor]="inputId()">
2
+ <app-input
3
+ type="search"
4
+ [placeholder]="config().placeholder ?? 'Search...'"
5
+ [value]="localValue()"
6
+ (valueChange)="onValueChange($event)"
7
+ />
8
+ </app-filter-field-wrapper>
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import {
7
+ ChangeDetectionStrategy,
8
+ Component,
9
+ DestroyRef,
10
+ effect,
11
+ inject,
12
+ input,
13
+ signal,
14
+ } from "@angular/core";
15
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
16
+ import { Subject } from "rxjs";
17
+ import { debounceTime } from "rxjs/operators";
18
+ // Base-app UI wrapper, inherited (not recreated) by this feature. Post-compose
19
+ // it lands at uiBundles/<target>/src/app/components/ui/input/..., three levels up.
20
+ import { InputComponent } from "../../../components/ui/input/input";
21
+ import { ObjectSearchStateService } from "../object-search-state.service";
22
+ import { FILTER_DEBOUNCE_MS } from "../utils/debounce";
23
+ import type { FilterFieldConfig } from "../utils/filter-utils";
24
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
25
+
26
+ /**
27
+ * Multi-field search filter — a debounced input whose value is applied via
28
+ * `like %value%` across every field named in `config.searchFields` (combined
29
+ * with a top-level `or`, see {@link buildFilter}).
30
+ *
31
+ * Shape mirrors {@link TextFilterComponent} but emits a `type: 'search'`
32
+ * {@link ActiveFilterValue} so `filter-utils` picks the multi-field path.
33
+ */
34
+ @Component({
35
+ selector: "app-search-filter",
36
+ changeDetection: ChangeDetectionStrategy.OnPush,
37
+ imports: [InputComponent, FilterFieldWrapperComponent],
38
+ templateUrl: "./search-filter.html",
39
+ })
40
+ export class SearchFilterComponent {
41
+ private readonly state = inject(ObjectSearchStateService);
42
+ private readonly destroyRef = inject(DestroyRef);
43
+
44
+ /** Field config: `field`, `label`, `placeholder`, `searchFields`, ... */
45
+ readonly config = input.required<FilterFieldConfig>();
46
+
47
+ protected readonly localValue = signal<string>("");
48
+ protected readonly inputId = signal<string>("");
49
+ private readonly commit$ = new Subject<string>();
50
+
51
+ constructor() {
52
+ this.commit$
53
+ .pipe(debounceTime(FILTER_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
54
+ .subscribe((v) => this.commit(v));
55
+
56
+ effect(() => {
57
+ const cfg = this.config();
58
+ this.inputId.set(`filter-${cfg.field}`);
59
+ const external = this.state.filterFor(cfg.field)?.value ?? "";
60
+ this.localValue.set(external);
61
+ });
62
+ }
63
+
64
+ protected onValueChange(v: string): void {
65
+ this.localValue.set(v);
66
+ this.commit$.next(v);
67
+ }
68
+
69
+ private commit(v: string): void {
70
+ const cfg = this.config();
71
+ if (v) {
72
+ this.state.setFilter(cfg.field, {
73
+ field: cfg.field,
74
+ label: cfg.label,
75
+ type: "search",
76
+ value: v,
77
+ });
78
+ } else {
79
+ this.state.removeFilter(cfg.field);
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,12 @@
1
+ <app-filter-field-wrapper
2
+ [label]="config().label"
3
+ [htmlFor]="inputId()"
4
+ [helpText]="config().helpText"
5
+ >
6
+ <app-select
7
+ [placeholder]="'Select ' + config().label.toLowerCase()"
8
+ [options]="options()"
9
+ [value]="currentValue()"
10
+ (valueChange)="onValueChange($event)"
11
+ />
12
+ </app-filter-field-wrapper>
@@ -0,0 +1,65 @@
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, computed, inject, input } from "@angular/core";
7
+ // Base-app UI wrapper, inherited (not recreated) by this feature. Post-compose
8
+ // it lands at uiBundles/<target>/src/app/components/ui/select/..., three levels up.
9
+ import {
10
+ SelectComponent,
11
+ type AppSelectOption,
12
+ } from "../../../components/ui/select/select";
13
+ import { ObjectSearchStateService } from "../object-search-state.service";
14
+ import type { FilterFieldConfig } from "../utils/filter-utils";
15
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
16
+
17
+ /**
18
+ * Single-value picklist filter — a select rendered from `config.options` with
19
+ * a leading "All" entry (empty value) that clears the filter.
20
+ *
21
+ * Emits a `type: 'picklist'` filter which `buildSingleFilter` maps to
22
+ * `{ [field]: { eq: value } }`.
23
+ */
24
+ const ALL_VALUE = "";
25
+
26
+ @Component({
27
+ selector: "app-select-filter",
28
+ changeDetection: ChangeDetectionStrategy.OnPush,
29
+ imports: [SelectComponent, FilterFieldWrapperComponent],
30
+ templateUrl: "./select-filter.html",
31
+ })
32
+ export class SelectFilterComponent {
33
+ private readonly state = inject(ObjectSearchStateService);
34
+
35
+ /** Field config: `field`, `label`, `options`, `helpText`, ... */
36
+ readonly config = input.required<FilterFieldConfig>();
37
+
38
+ /** DOM id shared by the wrapper label and the underlying control. */
39
+ protected readonly inputId = computed(() => `filter-${this.config().field}`);
40
+
41
+ /** Options rendered in the select, with an "All" (clear) sentinel prepended. */
42
+ protected readonly options = computed<readonly AppSelectOption[]>(() => [
43
+ { value: ALL_VALUE, label: "All" },
44
+ ...(this.config().options ?? []),
45
+ ]);
46
+
47
+ /** Current selection, reading through to shared state so URL changes reflect. */
48
+ protected readonly currentValue = computed(
49
+ () => this.state.filterFor(this.config().field)?.value ?? ALL_VALUE,
50
+ );
51
+
52
+ protected onValueChange(v: string): void {
53
+ const cfg = this.config();
54
+ if (v === ALL_VALUE) {
55
+ this.state.removeFilter(cfg.field);
56
+ } else {
57
+ this.state.setFilter(cfg.field, {
58
+ field: cfg.field,
59
+ label: cfg.label,
60
+ type: "picklist",
61
+ value: v,
62
+ });
63
+ }
64
+ }
65
+ }