@salesforce/ui-bundle-template-feature-angular-object-search 12.5.4

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 (289) hide show
  1. package/LICENSE.txt +82 -0
  2. package/README.md +101 -0
  3. package/dist/.forceignore +15 -0
  4. package/dist/.husky/pre-commit +4 -0
  5. package/dist/.prettierignore +11 -0
  6. package/dist/.prettierrc +17 -0
  7. package/dist/CHANGELOG.md +5238 -0
  8. package/dist/README.md +77 -0
  9. package/dist/config/project-scratch-def.json +13 -0
  10. package/dist/eslint.config.js +7 -0
  11. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/.forceignore +15 -0
  12. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/.graphqlrc.yml +2 -0
  13. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/.postcssrc.json +5 -0
  14. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/.prettierignore +8 -0
  15. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/.prettierrc +12 -0
  16. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/CHANGELOG.md +4 -0
  17. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/README.md +85 -0
  18. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/angular.json +98 -0
  19. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/codegen.yml +95 -0
  20. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/components.json +6 -0
  21. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/e2e/app.spec.ts +15 -0
  22. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/esbuild/api-version.mjs +17 -0
  23. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/esbuild/graphql-codegen.mjs +13 -0
  24. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/eslint-plugin-angular-graphql.js +148 -0
  25. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/eslint.config.js +76 -0
  26. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/feature-angular-object-search.uibundle-meta.xml +7 -0
  27. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/middleware/html.mjs +3 -0
  28. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/middleware/proxy.mjs +12 -0
  29. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/package.json +69 -0
  30. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/playwright.config.ts +25 -0
  31. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/public/favicon.ico +0 -0
  32. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/scripts/get-graphql-schema.mjs +69 -0
  33. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/scripts/rewrite-e2e-assets.mjs +30 -0
  34. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/account/account-search.service.ts +108 -0
  35. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/account/distinctAccountIndustries.ts +26 -0
  36. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/account/distinctAccountTypes.ts +26 -0
  37. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/account/getAccountDetail.ts +128 -0
  38. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/account/searchAccounts.ts +58 -0
  39. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/data-client.service.spec.ts +184 -0
  40. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/data-client.service.ts +74 -0
  41. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/api/graphql-operations-types.ts +29389 -0
  42. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/app.config.ts +20 -0
  43. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/app.html +1 -0
  44. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/app.routes.ts +32 -0
  45. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/app.spec.ts +18 -0
  46. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/app.ts +15 -0
  47. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/layout/app-layout/app-layout.html +51 -0
  48. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/layout/app-layout/app-layout.spec.ts +63 -0
  49. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/layout/app-layout/app-layout.ts +27 -0
  50. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/alert/alert.html +27 -0
  51. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/alert/alert.ts +41 -0
  52. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/button/button.html +27 -0
  53. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/button/button.ts +66 -0
  54. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/card/card.ts +100 -0
  55. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/collapsible/collapsible.html +38 -0
  56. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/collapsible/collapsible.ts +21 -0
  57. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/date-picker/date-picker.html +20 -0
  58. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/date-picker/date-picker.ts +49 -0
  59. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/date-range-picker/date-range-picker.html +20 -0
  60. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/date-range-picker/date-range-picker.ts +69 -0
  61. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/dialog/dialog.html +20 -0
  62. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/dialog/dialog.ts +40 -0
  63. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/dropdown-menu/dropdown-menu.html +20 -0
  64. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/dropdown-menu/dropdown-menu.ts +100 -0
  65. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/field/field.html +15 -0
  66. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/field/field.ts +28 -0
  67. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/field-appearance.ts +8 -0
  68. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/field-size.ts +8 -0
  69. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/icon/icon.ts +68 -0
  70. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/input/input.html +34 -0
  71. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/input/input.ts +79 -0
  72. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/label/label.ts +21 -0
  73. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/paginator/paginator.html +74 -0
  74. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/paginator/paginator.ts +93 -0
  75. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/paginator/types.ts +13 -0
  76. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/popover/popover.html +13 -0
  77. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/popover/popover.ts +37 -0
  78. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/select/select.html +36 -0
  79. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/select/select.ts +63 -0
  80. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/separator/separator.ts +31 -0
  81. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/skeleton/skeleton.ts +20 -0
  82. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/components/ui/spinner/spinner.ts +28 -0
  83. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/api/object-search.service.ts +94 -0
  84. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/breadcrumb/breadcrumb.html +34 -0
  85. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/breadcrumb/breadcrumb.ts +27 -0
  86. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/active-filters.html +23 -0
  87. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/active-filters.ts +78 -0
  88. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/date-filter.html +18 -0
  89. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/date-filter.ts +137 -0
  90. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/date-range-filter.html +12 -0
  91. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/date-range-filter.ts +60 -0
  92. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/filter-field-wrapper.html +13 -0
  93. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/filter-field-wrapper.ts +21 -0
  94. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/multi-select-filter.html +11 -0
  95. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/multi-select-filter.ts +58 -0
  96. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/numeric-range-filter.html +22 -0
  97. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/numeric-range-filter.ts +128 -0
  98. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/search-filter.html +8 -0
  99. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/search-filter.ts +78 -0
  100. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/select-filter.html +9 -0
  101. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/select-filter.ts +51 -0
  102. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/text-filter.html +9 -0
  103. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/filters/text-filter.ts +76 -0
  104. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/object-search-state.service.ts +232 -0
  105. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/pagination/pagination.html +8 -0
  106. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/pagination/pagination.ts +45 -0
  107. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/search-bar/search-bar.html +10 -0
  108. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/search-bar/search-bar.ts +28 -0
  109. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/sort-control/sort-control.html +24 -0
  110. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/sort-control/sort-control.ts +65 -0
  111. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/utils/debounce.ts +31 -0
  112. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/utils/field-utils.ts +54 -0
  113. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/utils/filter-utils.ts +354 -0
  114. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/utils/index.ts +12 -0
  115. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/features/object-search/utils/sort-utils.ts +39 -0
  116. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/account-detail/account-detail-page.html +142 -0
  117. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/account-detail/account-detail-page.ts +176 -0
  118. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/account-search/account-search-page.html +93 -0
  119. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/account-search/account-search-page.ts +196 -0
  120. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/home/home.html +17 -0
  121. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/home/home.spec.ts +25 -0
  122. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/home/home.ts +65 -0
  123. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/not-found/not-found.html +12 -0
  124. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/not-found/not-found.spec.ts +33 -0
  125. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/pages/not-found/not-found.ts +15 -0
  126. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/alert/hlm-alert-action.ts +14 -0
  127. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/alert/hlm-alert-description.ts +17 -0
  128. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/alert/hlm-alert-title.ts +17 -0
  129. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/alert/hlm-alert.ts +35 -0
  130. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/alert/index.ts +16 -0
  131. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/button/hlm-button.token.ts +22 -0
  132. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/button/hlm-button.ts +72 -0
  133. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/button/index.ts +6 -0
  134. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/calendar/hlm-calendar-multi.ts +195 -0
  135. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/calendar/hlm-calendar-range.ts +194 -0
  136. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/calendar/hlm-calendar.ts +189 -0
  137. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/calendar/hlm-month-year-calendar.ts +119 -0
  138. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/calendar/index.ts +16 -0
  139. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-action.ts +12 -0
  140. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-avatar.ts +14 -0
  141. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-content.ts +12 -0
  142. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-description.ts +12 -0
  143. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-footer.ts +12 -0
  144. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-header.ts +15 -0
  145. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card-title.ts +12 -0
  146. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card.token.ts +19 -0
  147. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/hlm-card.ts +22 -0
  148. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/card/index.ts +28 -0
  149. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/collapsible/hlm-collapsible-content.ts +14 -0
  150. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/collapsible/hlm-collapsible-trigger.ts +9 -0
  151. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/collapsible/hlm-collapsible.ts +15 -0
  152. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/collapsible/index.ts +13 -0
  153. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-multi-input.ts +104 -0
  154. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker-anchor.ts +23 -0
  155. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker-input.ts +118 -0
  156. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker-multi.token.ts +109 -0
  157. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker-multi.ts +220 -0
  158. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker-trigger.ts +104 -0
  159. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker.token.ts +69 -0
  160. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-picker.ts +203 -0
  161. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-range-input.ts +120 -0
  162. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-range-picker.token.ts +86 -0
  163. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-date-range-picker.ts +252 -0
  164. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-month-year-input.ts +105 -0
  165. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-month-year-picker.token.ts +89 -0
  166. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/hlm-month-year-picker.ts +196 -0
  167. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/date-picker/index.ts +38 -0
  168. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-close.ts +9 -0
  169. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-content.ts +74 -0
  170. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-description.ts +17 -0
  171. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-footer.ts +15 -0
  172. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-header.ts +12 -0
  173. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-overlay.ts +27 -0
  174. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-portal.ts +8 -0
  175. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-title.ts +14 -0
  176. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog-trigger.ts +14 -0
  177. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog.service.ts +46 -0
  178. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/hlm-dialog.ts +24 -0
  179. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dialog/index.ts +35 -0
  180. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox-indicator.ts +21 -0
  181. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-checkbox.ts +54 -0
  182. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-focus-on-hover.ts +35 -0
  183. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-group.ts +14 -0
  184. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-item-sub-indicator.ts +19 -0
  185. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-item.ts +42 -0
  186. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-label.ts +20 -0
  187. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio-indicator.ts +21 -0
  188. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-radio.ts +49 -0
  189. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-separator.ts +12 -0
  190. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-shortcut.ts +15 -0
  191. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub-trigger.ts +52 -0
  192. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-sub.ts +53 -0
  193. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-token.ts +26 -0
  194. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu-trigger.ts +46 -0
  195. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/hlm-dropdown-menu.ts +57 -0
  196. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/dropdown-menu/index.ts +49 -0
  197. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-content.ts +12 -0
  198. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-description.ts +53 -0
  199. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-error.ts +100 -0
  200. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-group.ts +15 -0
  201. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-label.ts +17 -0
  202. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-legend.ts +19 -0
  203. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-separator.ts +24 -0
  204. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-set.ts +15 -0
  205. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field-title.ts +15 -0
  206. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/hlm-field.ts +47 -0
  207. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/field/index.ts +34 -0
  208. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input/hlm-input.ts +21 -0
  209. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input/index.ts +5 -0
  210. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input-group/hlm-input-group-addon.ts +40 -0
  211. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input-group/hlm-input-group-button.ts +47 -0
  212. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input-group/hlm-input-group-input.ts +17 -0
  213. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input-group/hlm-input-group-text.ts +14 -0
  214. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input-group/hlm-input-group.ts +18 -0
  215. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/input-group/index.ts +19 -0
  216. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/label/hlm-label.ts +17 -0
  217. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/label/index.ts +5 -0
  218. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/label/label.html +11 -0
  219. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-numbered-pagination-query-params.ts +191 -0
  220. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-numbered-pagination.ts +290 -0
  221. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination-content.ts +12 -0
  222. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination-ellipsis.ts +27 -0
  223. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination-item.ts +7 -0
  224. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination-link.ts +51 -0
  225. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination-next.ts +65 -0
  226. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination-previous.ts +65 -0
  227. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/hlm-pagination.ts +19 -0
  228. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/pagination/index.ts +31 -0
  229. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover-content.ts +25 -0
  230. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover-description.ts +12 -0
  231. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover-header.ts +12 -0
  232. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover-portal.ts +8 -0
  233. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover-title.ts +12 -0
  234. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover-trigger.ts +14 -0
  235. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/hlm-popover.ts +23 -0
  236. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/popover/index.ts +25 -0
  237. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-content.ts +44 -0
  238. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-group.ts +14 -0
  239. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-item.ts +36 -0
  240. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-label.ts +14 -0
  241. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-multiple.ts +37 -0
  242. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-placeholder.ts +17 -0
  243. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-portal.ts +8 -0
  244. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-scroll-down.ts +22 -0
  245. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-scroll-up.ts +22 -0
  246. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-separator.ts +14 -0
  247. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-trigger.ts +59 -0
  248. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-value-template.ts +5 -0
  249. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-value.ts +18 -0
  250. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-values-content.ts +9 -0
  251. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select-values.ts +5 -0
  252. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/hlm-select.ts +37 -0
  253. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/select/index.ts +52 -0
  254. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/separator/hlm-separator.ts +19 -0
  255. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/separator/index.ts +5 -0
  256. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/skeleton/hlm-skeleton.ts +14 -0
  257. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/skeleton/index.ts +5 -0
  258. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/spinner/hlm-spinner.ts +26 -0
  259. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/spinner/index.ts +5 -0
  260. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/utils/hlm.ts +313 -0
  261. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/utils/index.ts +2 -0
  262. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/shared/utils/provide-spartan-hlm.ts +34 -0
  263. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/app/utils/async-data.ts +99 -0
  264. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/index.html +13 -0
  265. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/main.ts +5 -0
  266. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/styles.css +139 -0
  267. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/src/types/sf-globals.d.ts +9 -0
  268. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/tsconfig.app.json +11 -0
  269. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/tsconfig.json +36 -0
  270. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/tsconfig.spec.json +10 -0
  271. package/dist/force-app/main/default/uiBundles/feature-angular-object-search/ui-bundle.json +7 -0
  272. package/dist/jest.config.js +6 -0
  273. package/dist/package-lock.json +12554 -0
  274. package/dist/package.json +46 -0
  275. package/dist/scripts/apex/hello.apex +10 -0
  276. package/dist/scripts/gitignore-templates.json +4 -0
  277. package/dist/scripts/graphql-search.sh +191 -0
  278. package/dist/scripts/org-setup-config-schema.mjs +132 -0
  279. package/dist/scripts/org-setup-dev.mjs +114 -0
  280. package/dist/scripts/org-setup-url.mjs +108 -0
  281. package/dist/scripts/org-setup-utils.mjs +569 -0
  282. package/dist/scripts/org-setup-xml.mjs +278 -0
  283. package/dist/scripts/org-setup.config.json +5 -0
  284. package/dist/scripts/org-setup.mjs +2537 -0
  285. package/dist/scripts/sf-project-setup.mjs +103 -0
  286. package/dist/scripts/soql/account.soql +6 -0
  287. package/dist/scripts/validate-org-setup-config.mjs +38 -0
  288. package/dist/sfdx-project.json +12 -0
  289. package/package.json +51 -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 | undefined): 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,12 @@
1
+ <app-filter-field-wrapper [helpText]="config().helpText">
2
+ <app-date-range-picker
3
+ class="w-full"
4
+ [label]="config().label"
5
+ startPlaceholder="Start"
6
+ endPlaceholder="End"
7
+ [readonly]="true"
8
+ [max]="maxDate()"
9
+ [value]="range()"
10
+ (valueChange)="onRangeChange($event)"
11
+ />
12
+ </app-filter-field-wrapper>
@@ -0,0 +1,60 @@
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 {
8
+ DateRange,
9
+ DateRangePickerComponent,
10
+ } from "../../../components/ui/date-range-picker/date-range-picker";
11
+ import { ObjectSearchStateService } from "../object-search-state.service";
12
+ import type { FilterFieldConfig, FilterFieldType } from "../utils/filter-utils";
13
+ import { toDate, toDateString } from "./date-filter";
14
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
15
+
16
+ /**
17
+ * Date range filter — a two-ended range picker. Emits a `daterange` (or
18
+ * `datetimerange`) filter with `min` / `max` as `YYYY-MM-DD` strings.
19
+ */
20
+ @Component({
21
+ selector: "app-date-range-filter",
22
+ changeDetection: ChangeDetectionStrategy.OnPush,
23
+ imports: [DateRangePickerComponent, FilterFieldWrapperComponent],
24
+ templateUrl: "./date-range-filter.html",
25
+ })
26
+ export class DateRangeFilterComponent {
27
+ private readonly state = inject(ObjectSearchStateService);
28
+
29
+ readonly config = input.required<FilterFieldConfig>();
30
+ readonly filterType = input<FilterFieldType>("daterange");
31
+
32
+ private readonly active = computed(() => this.state.filterFor(this.config().field));
33
+
34
+ protected readonly range = computed<DateRange<Date>>(() => ({
35
+ start: toDate(this.active()?.min),
36
+ end: toDate(this.active()?.max),
37
+ }));
38
+
39
+ /** Cap the picker at today when the field can't hold a future date. */
40
+ protected readonly maxDate = computed<Date | null>(() =>
41
+ this.config().disableFuture ? new Date() : null,
42
+ );
43
+
44
+ protected onRangeChange(range: DateRange<Date> | null): void {
45
+ const cfg = this.config();
46
+ const from = range?.start ?? null;
47
+ const to = range?.end ?? null;
48
+ if (!from && !to) {
49
+ this.state.removeFilter(cfg.field);
50
+ return;
51
+ }
52
+ this.state.setFilter(cfg.field, {
53
+ field: cfg.field,
54
+ label: cfg.label,
55
+ type: this.filterType(),
56
+ min: toDateString(from),
57
+ max: toDateString(to),
58
+ });
59
+ }
60
+ }
@@ -0,0 +1,13 @@
1
+ <div class="space-y-1">
2
+ @if (label()) {
3
+ <app-label [for]="htmlFor()">{{ label() }}</app-label>
4
+ }
5
+ <ng-content />
6
+ <div class="min-h-4">
7
+ @if (error(); as err) {
8
+ <p class="text-xs text-red-600" role="alert">{{ err }}</p>
9
+ } @else if (helpText(); as help) {
10
+ <p class="text-xs text-gray-500">{{ help }}</p>
11
+ }
12
+ </div>
13
+ </div>
@@ -0,0 +1,21 @@
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
+ // Post-compose, this lands 3 levels up at app/components/ui/label/__inherit__label.
8
+ import { LabelComponent } from "../../../components/ui/label/label";
9
+
10
+ @Component({
11
+ selector: "app-filter-field-wrapper",
12
+ changeDetection: ChangeDetectionStrategy.OnPush,
13
+ imports: [LabelComponent],
14
+ templateUrl: "./filter-field-wrapper.html",
15
+ })
16
+ export class FilterFieldWrapperComponent {
17
+ readonly label = input<string>("");
18
+ readonly htmlFor = input<string | null>(null);
19
+ readonly helpText = input<string | undefined>(undefined);
20
+ readonly error = input<string | undefined>(undefined);
21
+ }
@@ -0,0 +1,11 @@
1
+ <app-filter-field-wrapper [helpText]="config().helpText">
2
+ <app-select
3
+ multiple
4
+ [label]="config().label"
5
+ [size]="size()"
6
+ [options]="config().options ?? []"
7
+ [placeholder]="placeholder()"
8
+ [values]="selected()"
9
+ (valuesChange)="onSelectionChange($event)"
10
+ />
11
+ </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,128 @@
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 { InputComponent } from "../../../components/ui/input/input";
20
+ import { ObjectSearchStateService } from "../object-search-state.service";
21
+ import { FILTER_DEBOUNCE_MS } from "../utils/debounce";
22
+ import type { FilterFieldConfig } from "../utils/filter-utils";
23
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
24
+
25
+ /**
26
+ * Numeric range filter — paired `min` / `max` inputs whose committed values are
27
+ * written as strings on a `type: 'numeric'` filter (numeric coercion happens
28
+ * in `buildSingleFilter`). A trailing debounce commits the pair, skipping
29
+ * writes when the range is inverted or out of `boundMin` / `boundMax`.
30
+ */
31
+ @Component({
32
+ selector: "app-numeric-range-filter",
33
+ changeDetection: ChangeDetectionStrategy.OnPush,
34
+ imports: [InputComponent, FilterFieldWrapperComponent],
35
+ templateUrl: "./numeric-range-filter.html",
36
+ })
37
+ export class NumericRangeFilterComponent {
38
+ private readonly state = inject(ObjectSearchStateService);
39
+ private readonly destroyRef = inject(DestroyRef);
40
+
41
+ readonly config = input.required<FilterFieldConfig>();
42
+ readonly boundMin = input<number | undefined>(undefined);
43
+ readonly boundMax = input<number | undefined>(undefined);
44
+
45
+ protected readonly localMin = signal<string>("");
46
+ protected readonly localMax = signal<string>("");
47
+
48
+ private readonly commit$ = new Subject<{ min: string; max: string }>();
49
+
50
+ constructor() {
51
+ this.commit$
52
+ .pipe(debounceTime(FILTER_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
53
+ .subscribe(({ min, max }) => this.commit(min, max));
54
+
55
+ // Sync local inputs from shared state (URL restore / reset-all).
56
+ effect(() => {
57
+ const cfg = this.config();
58
+ const active = this.state.filterFor(cfg.field);
59
+ this.localMin.set(active?.min ?? "");
60
+ this.localMax.set(active?.max ?? "");
61
+ });
62
+ }
63
+
64
+ protected readonly minOutOfBounds = computed(() => this.isOutOfBounds(this.localMin()));
65
+ protected readonly maxOutOfBounds = computed(() => this.isOutOfBounds(this.localMax()));
66
+ protected readonly isRangeInverted = computed(() => {
67
+ const lo = this.localMin();
68
+ const hi = this.localMax();
69
+ return lo !== "" && hi !== "" && Number(lo) > Number(hi);
70
+ });
71
+ protected readonly hasError = computed(
72
+ () => this.minOutOfBounds() || this.maxOutOfBounds() || this.isRangeInverted(),
73
+ );
74
+
75
+ protected readonly errorMessage = computed<string | undefined>(() => {
76
+ if (this.isRangeInverted()) return "Min must not exceed max";
77
+ if (!this.minOutOfBounds() && !this.maxOutOfBounds()) return undefined;
78
+ const lo = this.boundMin();
79
+ const hi = this.boundMax();
80
+ if (lo != null && hi != null) return `Value must be between ${lo}–${hi}`;
81
+ if (lo != null) return `Value must be ${lo} or more`;
82
+ if (hi != null) return `Value must be ${hi} or less`;
83
+ return undefined;
84
+ });
85
+
86
+ protected onMinChange(v: string): void {
87
+ this.localMin.set(v);
88
+ this.commit$.next({ min: v, max: this.localMax() });
89
+ }
90
+
91
+ protected onMaxChange(v: string): void {
92
+ this.localMax.set(v);
93
+ this.commit$.next({ min: this.localMin(), max: v });
94
+ }
95
+
96
+ private isOutOfBounds(v: string): boolean {
97
+ if (v === "") return false;
98
+ const n = Number(v);
99
+ const lo = this.boundMin();
100
+ const hi = this.boundMax();
101
+ return (lo != null && n < lo) || (hi != null && n > hi);
102
+ }
103
+
104
+ private commit(min: string, max: string): void {
105
+ const cfg = this.config();
106
+ if (!min && !max) {
107
+ this.state.removeFilter(cfg.field);
108
+ return;
109
+ }
110
+ const minNum = min !== "" ? Number(min) : null;
111
+ const maxNum = max !== "" ? Number(max) : null;
112
+ // Skip writes that would produce an inverted or out-of-bounds clause;
113
+ // the UI keeps the input contents so the user can correct in place.
114
+ if (minNum != null && maxNum != null && minNum > maxNum) return;
115
+ const lo = this.boundMin();
116
+ const hi = this.boundMax();
117
+ if (minNum != null && ((lo != null && minNum < lo) || (hi != null && minNum > hi))) return;
118
+ if (maxNum != null && ((lo != null && maxNum < lo) || (hi != null && maxNum > hi))) return;
119
+
120
+ this.state.setFilter(cfg.field, {
121
+ field: cfg.field,
122
+ label: cfg.label,
123
+ type: "numeric",
124
+ min,
125
+ max,
126
+ });
127
+ }
128
+ }
@@ -0,0 +1,8 @@
1
+ <app-filter-field-wrapper [label]="config().label" [htmlFor]="fieldId()">
2
+ <app-search-bar
3
+ [inputId]="fieldId()"
4
+ [placeholder]="config().placeholder ?? 'Search...'"
5
+ [value]="localValue()"
6
+ (valueChange)="onValueChange($event)"
7
+ />
8
+ </app-filter-field-wrapper>
@@ -0,0 +1,78 @@
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
+ computed,
10
+ DestroyRef,
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 { SearchBarComponent } from "../search-bar/search-bar";
20
+ import { ObjectSearchStateService } from "../object-search-state.service";
21
+ import { FILTER_DEBOUNCE_MS } from "../utils/debounce";
22
+ import type { FilterFieldConfig } from "../utils/filter-utils";
23
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
24
+
25
+ /**
26
+ * Multi-field search filter — a debounced input applied via `like %value%`
27
+ * across every field named in `config.searchFields` (combined with a
28
+ * top-level `or`, see {@link buildFilter}).
29
+ */
30
+ @Component({
31
+ selector: "app-search-filter",
32
+ changeDetection: ChangeDetectionStrategy.OnPush,
33
+ imports: [SearchBarComponent, FilterFieldWrapperComponent],
34
+ templateUrl: "./search-filter.html",
35
+ })
36
+ export class SearchFilterComponent {
37
+ private readonly state = inject(ObjectSearchStateService);
38
+ private readonly destroyRef = inject(DestroyRef);
39
+
40
+ readonly config = input.required<FilterFieldConfig>();
41
+
42
+ // Ties the wrapper's <label for> to the search input.
43
+ protected readonly fieldId = computed(() => `filter-${this.config().field}`);
44
+
45
+ protected readonly localValue = signal<string>("");
46
+ private readonly commit$ = new Subject<string>();
47
+
48
+ constructor() {
49
+ this.commit$
50
+ .pipe(debounceTime(FILTER_DEBOUNCE_MS), takeUntilDestroyed(this.destroyRef))
51
+ .subscribe((v) => this.commit(v));
52
+
53
+ effect(() => {
54
+ const cfg = this.config();
55
+ const external = this.state.filterFor(cfg.field)?.value ?? "";
56
+ this.localValue.set(external);
57
+ });
58
+ }
59
+
60
+ protected onValueChange(v: string): void {
61
+ this.localValue.set(v);
62
+ this.commit$.next(v);
63
+ }
64
+
65
+ private commit(v: string): void {
66
+ const cfg = this.config();
67
+ if (v) {
68
+ this.state.setFilter(cfg.field, {
69
+ field: cfg.field,
70
+ label: cfg.label,
71
+ type: "search",
72
+ value: v,
73
+ });
74
+ } else {
75
+ this.state.removeFilter(cfg.field);
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,9 @@
1
+ <app-filter-field-wrapper [helpText]="config().helpText">
2
+ <app-select
3
+ [label]="config().label"
4
+ [placeholder]="'Select ' + config().label.toLowerCase()"
5
+ [options]="options()"
6
+ [value]="currentValue()"
7
+ (valueChange)="onValueChange($event)"
8
+ />
9
+ </app-filter-field-wrapper>
@@ -0,0 +1,51 @@
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 {
8
+ SelectComponent,
9
+ type AppSelectOption,
10
+ } from "../../../components/ui/select/select";
11
+ import { ObjectSearchStateService } from "../object-search-state.service";
12
+ import type { FilterFieldConfig } from "../utils/filter-utils";
13
+ import { FilterFieldWrapperComponent } from "./filter-field-wrapper";
14
+
15
+ // A leading "All" entry (empty value) clears the filter.
16
+ const ALL_VALUE = "";
17
+
18
+ @Component({
19
+ selector: "app-select-filter",
20
+ changeDetection: ChangeDetectionStrategy.OnPush,
21
+ imports: [SelectComponent, FilterFieldWrapperComponent],
22
+ templateUrl: "./select-filter.html",
23
+ })
24
+ export class SelectFilterComponent {
25
+ private readonly state = inject(ObjectSearchStateService);
26
+
27
+ readonly config = input.required<FilterFieldConfig>();
28
+
29
+ protected readonly options = computed<readonly AppSelectOption[]>(() => [
30
+ { value: ALL_VALUE, label: "All" },
31
+ ...(this.config().options ?? []),
32
+ ]);
33
+
34
+ protected readonly currentValue = computed(
35
+ () => this.state.filterFor(this.config().field)?.value ?? ALL_VALUE,
36
+ );
37
+
38
+ protected onValueChange(v: string): void {
39
+ const cfg = this.config();
40
+ if (v === ALL_VALUE) {
41
+ this.state.removeFilter(cfg.field);
42
+ } else {
43
+ this.state.setFilter(cfg.field, {
44
+ field: cfg.field,
45
+ label: cfg.label,
46
+ type: "picklist",
47
+ value: v,
48
+ });
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,9 @@
1
+ <app-filter-field-wrapper [helpText]="config().helpText">
2
+ <app-input
3
+ type="text"
4
+ [label]="config().label"
5
+ [placeholder]="config().placeholder ?? 'Filter by ' + config().label.toLowerCase() + '...'"
6
+ [value]="localValue()"
7
+ (valueChange)="onValueChange($event)"
8
+ />
9
+ </app-filter-field-wrapper>