@salesforce/templates 66.13.5 → 66.13.7

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 (281) hide show
  1. package/lib/templates/project/angularextapp/CHANGELOG.md +258 -0
  2. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +1 -1
  3. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
  4. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
  5. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +680 -408
  6. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +2 -2
  7. package/lib/templates/project/angularextapp/package.json +1 -1
  8. package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +17 -0
  9. package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +33 -3
  10. package/lib/templates/project/angularextapp/scripts/org-setup.mjs +535 -3
  11. package/lib/templates/project/angularintapp/CHANGELOG.md +266 -0
  12. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +1 -1
  13. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
  14. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
  15. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +690 -418
  16. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +2 -2
  17. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +6 -1
  18. package/lib/templates/project/angularintapp/package.json +1 -1
  19. package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +17 -0
  20. package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +33 -3
  21. package/lib/templates/project/angularintapp/scripts/org-setup.mjs +535 -3
  22. package/lib/templates/project/reactexternalapp/CHANGELOG.md +1409 -0
  23. package/lib/templates/project/reactexternalapp/PRD.md +38 -0
  24. package/lib/templates/project/reactexternalapp/README.md +14 -10
  25. package/lib/templates/project/reactexternalapp/_p_/_m_/_ps_/reactexternalapp_Guest_User_Api_Access.permissionset-meta.xml +25 -0
  26. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +953 -714
  27. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +9 -7
  28. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +8 -5
  29. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/LanguageSwitcher.tsx +116 -0
  30. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/__examples__/language-switcher-example.tsx +36 -0
  31. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/__examples__/vite-config-site-example.ts +44 -0
  32. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/buildLanguageUrl.ts +158 -0
  33. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/index.ts +28 -0
  34. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/languages.ts +46 -0
  35. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/components/SocialLogin.tsx +141 -0
  36. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Login.tsx +2 -0
  37. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/README.md +246 -0
  38. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/apiUtils.ts +56 -0
  39. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/orgApiVersionService.ts +37 -0
  40. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/searchableContentTypesService.ts +116 -0
  41. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/channelResolver.ts +40 -0
  42. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/cmsQueryFragment.ts +97 -0
  43. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeSessionCache.ts +134 -0
  44. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeUtils.ts +38 -0
  45. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/hooks/useSearchableContentTypes.ts +128 -0
  46. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/index.ts +54 -0
  47. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/parseResponse.ts +65 -0
  48. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/searchChannel.ts +15 -0
  49. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/types.ts +66 -0
  50. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/registry.ts +38 -0
  51. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/index.ts +19 -0
  52. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/parseResponse.ts +56 -0
  53. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/queryFragment.ts +141 -0
  54. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/types.ts +101 -0
  55. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
  56. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +136 -0
  57. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.tsx +98 -0
  58. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +294 -0
  59. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +203 -0
  60. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +88 -0
  61. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +187 -0
  62. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
  63. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +107 -0
  64. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
  65. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
  66. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
  67. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
  68. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
  69. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  70. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
  71. package/lib/templates/project/{reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters → reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs}/FilterFieldWrapper.tsx +11 -6
  72. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
  73. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
  74. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
  75. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
  76. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/CmsResultRow.tsx +101 -0
  77. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
  78. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/resolveResultRenderer.ts +49 -0
  79. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +88 -0
  80. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/constants.ts +8 -0
  81. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
  82. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
  83. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +966 -0
  84. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +115 -0
  85. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  86. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +100 -0
  87. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +376 -0
  88. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  89. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  90. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
  91. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  92. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphqlClient.ts +24 -8
  93. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/appLayout.tsx +7 -0
  94. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/CustomerWebClientChat.tsx +74 -0
  95. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
  96. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  97. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
  98. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
  99. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/index.ts +8 -0
  100. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +53 -18
  101. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +3 -27
  102. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/TestChatPage.tsx +26 -0
  103. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +21 -8
  104. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/types/chat.ts +36 -0
  105. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/types/globals.d.ts +23 -0
  106. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
  107. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
  108. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  109. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls +133 -0
  110. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls-meta.xml +5 -0
  111. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls +101 -0
  112. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls-meta.xml +5 -0
  113. package/lib/templates/project/reactexternalapp/_p_/_m_/package.xml +4 -0
  114. package/lib/templates/project/reactexternalapp/package.json +8 -2
  115. package/lib/templates/project/reactexternalapp/scripts/org-setup-config-schema.mjs +120 -0
  116. package/lib/templates/project/reactexternalapp/scripts/org-setup-dev.mjs +87 -0
  117. package/lib/templates/project/reactexternalapp/scripts/org-setup-utils.mjs +569 -0
  118. package/lib/templates/project/reactexternalapp/scripts/org-setup-xml.mjs +182 -0
  119. package/lib/templates/project/reactexternalapp/scripts/org-setup.config.json +6 -2
  120. package/lib/templates/project/reactexternalapp/scripts/org-setup.mjs +1509 -328
  121. package/lib/templates/project/reactexternalapp/scripts/validate-org-setup-config.mjs +38 -0
  122. package/lib/templates/project/reactinternalapp/CHANGELOG.md +1223 -0
  123. package/lib/templates/project/reactinternalapp/PRD.md +35 -0
  124. package/lib/templates/project/reactinternalapp/README.md +14 -10
  125. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +813 -538
  126. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package.json +10 -9
  127. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/README.md +246 -0
  128. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/apiUtils.ts +56 -0
  129. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/orgApiVersionService.ts +37 -0
  130. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/searchableContentTypesService.ts +116 -0
  131. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/channelResolver.ts +40 -0
  132. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/cmsQueryFragment.ts +97 -0
  133. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeSessionCache.ts +134 -0
  134. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeUtils.ts +38 -0
  135. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/hooks/useSearchableContentTypes.ts +128 -0
  136. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/index.ts +54 -0
  137. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/parseResponse.ts +65 -0
  138. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/searchChannel.ts +15 -0
  139. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/types.ts +66 -0
  140. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/registry.ts +38 -0
  141. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/index.ts +19 -0
  142. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/parseResponse.ts +56 -0
  143. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/queryFragment.ts +141 -0
  144. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/types.ts +101 -0
  145. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
  146. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +136 -0
  147. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.tsx +98 -0
  148. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +294 -0
  149. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +203 -0
  150. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +88 -0
  151. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +187 -0
  152. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
  153. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +107 -0
  154. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
  155. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
  156. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
  157. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
  158. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
  159. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  160. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
  161. package/lib/templates/project/{reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters → reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs}/FilterFieldWrapper.tsx +11 -6
  162. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
  163. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
  164. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
  165. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
  166. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/CmsResultRow.tsx +101 -0
  167. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
  168. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/resolveResultRenderer.ts +49 -0
  169. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +88 -0
  170. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/constants.ts +8 -0
  171. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
  172. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
  173. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +966 -0
  174. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +115 -0
  175. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  176. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +100 -0
  177. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +376 -0
  178. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  179. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  180. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
  181. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  182. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.tsx +16 -132
  183. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
  184. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  185. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
  186. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
  187. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +49 -16
  188. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +3 -27
  189. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +12 -5
  190. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
  191. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
  192. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  193. package/lib/templates/project/reactinternalapp/package.json +4 -2
  194. package/lib/templates/project/reactinternalapp/scripts/org-setup-config-schema.mjs +24 -0
  195. package/lib/templates/project/reactinternalapp/scripts/org-setup-dev.mjs +87 -0
  196. package/lib/templates/project/reactinternalapp/scripts/org-setup-utils.mjs +569 -0
  197. package/lib/templates/project/reactinternalapp/scripts/org-setup-xml.mjs +182 -0
  198. package/lib/templates/project/reactinternalapp/scripts/org-setup.mjs +1162 -214
  199. package/lib/templates/uiBundles/angularbasic/angular.json +1 -1
  200. package/lib/templates/uiBundles/angularbasic/eslint-plugin-angular-graphql.js +148 -0
  201. package/lib/templates/uiBundles/angularbasic/eslint.config.js +9 -1
  202. package/lib/templates/uiBundles/angularbasic/package-lock.json +680 -408
  203. package/lib/templates/uiBundles/angularbasic/package.json +2 -2
  204. package/lib/templates/uiBundles/reactbasic/package-lock.json +738 -440
  205. package/lib/utils/template-placeholders.js +14 -0
  206. package/lib/utils/template-placeholders.js.map +1 -1
  207. package/lib/utils/uiBundleTemplateUtils.d.ts +5 -1
  208. package/lib/utils/uiBundleTemplateUtils.js +7 -1
  209. package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
  210. package/package.json +7 -7
  211. package/lib/templates/project/reactexternalapp/AGENT.md +0 -252
  212. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
  213. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
  214. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
  215. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
  216. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
  217. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
  218. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
  219. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
  220. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
  221. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
  222. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
  223. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
  224. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
  225. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
  226. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
  227. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
  228. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
  229. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
  230. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
  231. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
  232. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
  233. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
  234. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
  235. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
  236. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
  237. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
  238. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
  239. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
  240. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
  241. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
  242. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
  243. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +0 -297
  244. package/lib/templates/project/reactexternalapp/scripts/prepare-import-unique-fields.js +0 -122
  245. package/lib/templates/project/reactinternalapp/AGENT.md +0 -252
  246. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
  247. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
  248. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
  249. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
  250. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
  251. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
  252. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
  253. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
  254. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
  255. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
  256. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
  257. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
  258. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
  259. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
  260. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
  261. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
  262. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
  263. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
  264. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
  265. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
  266. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
  267. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
  268. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
  269. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
  270. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
  271. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
  272. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
  273. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
  274. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
  275. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
  276. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
  277. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +0 -297
  278. package/lib/templates/project/reactinternalapp/scripts/prepare-import-unique-fields.js +0 -122
  279. /package/lib/templates/project/angularextapp/_p_/_m_/{permissionsets → _ps_}/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +0 -0
  280. /package/lib/templates/project/angularintapp/_p_/_m_/{permissionsets → _ps_}/angularintapp_Access.permissionset-meta.xml +0 -0
  281. /package/lib/templates/project/reactinternalapp/_p_/_m_/{permissionsets → _ps_}/reactinternalapp_Access.permissionset-meta.xml +0 -0
@@ -1,52 +0,0 @@
1
- import { useState } from "react";
2
-
3
- import { SearchBar } from "../SearchBar";
4
- import { useFilterField } from "../FilterContext";
5
- import { FilterFieldWrapper } from "./FilterFieldWrapper";
6
- import { useDebouncedCallback } from "../../hooks/useDebouncedCallback";
7
-
8
- interface SearchFilterProps extends Omit<React.ComponentProps<"div">, "onChange"> {
9
- field: string;
10
- label: string;
11
- placeholder?: string;
12
- }
13
-
14
- export function SearchFilter({
15
- field,
16
- label,
17
- placeholder,
18
- className,
19
- ...props
20
- }: SearchFilterProps) {
21
- const { value, onChange } = useFilterField(field);
22
- const [localValue, setLocalValue] = useState(value?.value ?? "");
23
-
24
- const externalValue = value?.value ?? "";
25
- const [prevExternalValue, setPrevExternalValue] = useState(externalValue);
26
- if (prevExternalValue !== externalValue) {
27
- setPrevExternalValue(externalValue);
28
- setLocalValue(externalValue);
29
- }
30
-
31
- const debouncedOnChange = useDebouncedCallback((v: string) => {
32
- if (v) {
33
- onChange({ field, label, type: "search", value: v });
34
- } else {
35
- onChange(undefined);
36
- }
37
- });
38
-
39
- return (
40
- <FilterFieldWrapper label={label} htmlFor={`filter-${field}`} className={className} {...props}>
41
- <SearchBar
42
- value={localValue}
43
- handleChange={(v) => {
44
- setLocalValue(v);
45
- debouncedOnChange(v);
46
- }}
47
- placeholder={placeholder}
48
- inputProps={{ id: `filter-${field}` }}
49
- />
50
- </FilterFieldWrapper>
51
- );
52
- }
@@ -1,97 +0,0 @@
1
- import {
2
- Select,
3
- SelectContent,
4
- SelectItem,
5
- SelectTrigger,
6
- SelectValue,
7
- } from "../../../../components/ui/select";
8
- import { cn } from "../../../../lib/utils";
9
- import { useFilterField } from "../FilterContext";
10
- import { FilterFieldWrapper } from "./FilterFieldWrapper";
11
- import type { ActiveFilterValue } from "../../utils/filterUtils";
12
-
13
- const ALL_VALUE = "__all__";
14
-
15
- interface SelectFilterProps extends Omit<React.ComponentProps<"div">, "onChange"> {
16
- field: string;
17
- label: string;
18
- options: Array<{ value: string; label: string }>;
19
- helpText?: string;
20
- }
21
-
22
- export function SelectFilter({
23
- field,
24
- label,
25
- options,
26
- helpText,
27
- className,
28
- ...props
29
- }: SelectFilterProps) {
30
- const { value, onChange } = useFilterField(field);
31
- return (
32
- <FilterFieldWrapper
33
- label={label}
34
- htmlFor={`filter-${field}`}
35
- helpText={helpText}
36
- className={className}
37
- {...props}
38
- >
39
- <SelectFilterControl
40
- field={field}
41
- label={label}
42
- options={options}
43
- value={value}
44
- onChange={onChange}
45
- />
46
- </FilterFieldWrapper>
47
- );
48
- }
49
-
50
- interface SelectFilterControlProps {
51
- field: string;
52
- label: string;
53
- options: Array<{ value: string; label: string }>;
54
- value: ActiveFilterValue | undefined;
55
- onChange: (value: ActiveFilterValue | undefined) => void;
56
- triggerProps?: React.ComponentProps<typeof SelectTrigger>;
57
- contentProps?: React.ComponentProps<typeof SelectContent>;
58
- }
59
-
60
- export function SelectFilterControl({
61
- field,
62
- label,
63
- options,
64
- value,
65
- onChange,
66
- triggerProps,
67
- contentProps,
68
- }: SelectFilterControlProps) {
69
- return (
70
- <Select
71
- value={value?.value ?? ALL_VALUE}
72
- onValueChange={(v) => {
73
- if (v === ALL_VALUE) {
74
- onChange(undefined);
75
- } else {
76
- onChange({ field, label, type: "picklist", value: v });
77
- }
78
- }}
79
- >
80
- <SelectTrigger
81
- id={`filter-${field}`}
82
- {...triggerProps}
83
- className={cn("w-full", triggerProps?.className)}
84
- >
85
- <SelectValue placeholder={`Select ${label.toLowerCase()}`} />
86
- </SelectTrigger>
87
- <SelectContent {...contentProps}>
88
- <SelectItem value={ALL_VALUE}>All</SelectItem>
89
- {options.map((opt) => (
90
- <SelectItem key={opt.value} value={opt.value}>
91
- {opt.label}
92
- </SelectItem>
93
- ))}
94
- </SelectContent>
95
- </Select>
96
- );
97
- }
@@ -1,93 +0,0 @@
1
- import { useState } from "react";
2
- import { Input } from "../../../../components/ui/input";
3
- import { cn } from "../../../../lib/utils";
4
- import { useFilterField } from "../FilterContext";
5
- import { FilterFieldWrapper } from "./FilterFieldWrapper";
6
- import { useDebouncedCallback } from "../../hooks/useDebouncedCallback";
7
- import type { ActiveFilterValue } from "../../utils/filterUtils";
8
-
9
- interface TextFilterProps extends Omit<React.ComponentProps<"div">, "onChange"> {
10
- field: string;
11
- label: string;
12
- placeholder?: string;
13
- helpText?: string;
14
- }
15
-
16
- export function TextFilter({
17
- field,
18
- label,
19
- placeholder,
20
- helpText,
21
- className,
22
- ...props
23
- }: TextFilterProps) {
24
- const { value, onChange } = useFilterField(field);
25
- return (
26
- <FilterFieldWrapper
27
- label={label}
28
- htmlFor={`filter-${field}`}
29
- helpText={helpText}
30
- className={className}
31
- {...props}
32
- >
33
- <TextFilterInput
34
- field={field}
35
- label={label}
36
- placeholder={placeholder}
37
- value={value}
38
- onChange={onChange}
39
- />
40
- </FilterFieldWrapper>
41
- );
42
- }
43
-
44
- interface TextFilterInputProps extends Omit<
45
- React.ComponentProps<typeof Input>,
46
- "onChange" | "value"
47
- > {
48
- field: string;
49
- label: string;
50
- value: ActiveFilterValue | undefined;
51
- onChange: (value: ActiveFilterValue | undefined) => void;
52
- }
53
-
54
- export function TextFilterInput({
55
- field,
56
- label,
57
- value,
58
- onChange,
59
- className,
60
- ...props
61
- }: TextFilterInputProps) {
62
- const [localValue, setLocalValue] = useState(value?.value ?? "");
63
-
64
- const externalValue = value?.value ?? "";
65
- const [prevExternalValue, setPrevExternalValue] = useState(externalValue);
66
- if (prevExternalValue !== externalValue) {
67
- setPrevExternalValue(externalValue);
68
- setLocalValue(externalValue);
69
- }
70
-
71
- const debouncedOnChange = useDebouncedCallback((v: string) => {
72
- if (v) {
73
- onChange({ field, label, type: "text", value: v });
74
- } else {
75
- onChange(undefined);
76
- }
77
- });
78
-
79
- return (
80
- <Input
81
- id={`filter-${field}`}
82
- type="text"
83
- placeholder={props.placeholder ?? `Filter by ${label.toLowerCase()}...`}
84
- value={localValue}
85
- onChange={(e) => {
86
- setLocalValue(e.target.value);
87
- debouncedOnChange(e.target.value);
88
- }}
89
- className={cn(className)}
90
- {...props}
91
- />
92
- );
93
- }
@@ -1,34 +0,0 @@
1
- import { useCallback, useEffect, useRef } from "react";
2
- import { debounce, FILTER_DEBOUNCE_MS } from "../utils/debounce";
3
-
4
- /**
5
- * Returns a stable debounced wrapper around the provided callback.
6
- *
7
- * The wrapper always invokes the *latest* version of `fn` (via a ref),
8
- * so the debounce timer is never reset when `fn` changes — only when
9
- * the caller invokes the returned function again.
10
- *
11
- * @param fn - The callback to debounce.
12
- * @param delay - Debounce delay in ms. Defaults to `FILTER_DEBOUNCE_MS`.
13
- */
14
- export function useDebouncedCallback<T extends (...args: any[]) => void>(
15
- fn: T,
16
- delay: number = FILTER_DEBOUNCE_MS,
17
- ): (...args: Parameters<T>) => void {
18
- const fnRef = useRef(fn);
19
- const debouncedRef = useRef<((...args: any[]) => void) | null>(null);
20
-
21
- useEffect(() => {
22
- fnRef.current = fn;
23
- });
24
-
25
- useEffect(() => {
26
- debouncedRef.current = debounce((...args: any[]) => {
27
- fnRef.current(...(args as Parameters<T>));
28
- }, delay);
29
- }, [delay]);
30
-
31
- return useCallback((...args: Parameters<T>) => {
32
- debouncedRef.current?.(...args);
33
- }, []);
34
- }
@@ -1,254 +0,0 @@
1
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
- import { useSearchParams } from "react-router";
3
- import type { FilterFieldConfig, ActiveFilterValue } from "../utils/filterUtils";
4
- import type { SortFieldConfig, SortState } from "../utils/sortUtils";
5
- import { filtersToSearchParams, searchParamsToFilters, buildFilter } from "../utils/filterUtils";
6
- import { buildOrderBy } from "../utils/sortUtils";
7
- import { debounce } from "../utils/debounce";
8
-
9
- /** How long to wait before flushing local state changes to the URL. */
10
- const URL_SYNC_DEBOUNCE_MS = 300;
11
-
12
- export interface PaginationConfig {
13
- defaultPageSize: number;
14
- validPageSizes: number[];
15
- }
16
-
17
- export interface UseObjectSearchParamsReturn<TFilter, TOrderBy> {
18
- filters: {
19
- active: ActiveFilterValue[];
20
- set: (field: string, value: ActiveFilterValue | undefined) => void;
21
- remove: (field: string) => void;
22
- };
23
- sort: {
24
- current: SortState | null;
25
- set: (sort: SortState | null) => void;
26
- };
27
- query: { where: TFilter; orderBy: TOrderBy };
28
- pagination: {
29
- pageSize: number;
30
- pageIndex: number;
31
- afterCursor: string | undefined;
32
- setPageSize: (size: number) => void;
33
- goToNextPage: (cursor: string) => void;
34
- goToPreviousPage: () => void;
35
- };
36
- resetAll: () => void;
37
- }
38
-
39
- /**
40
- * Manages filter, sort, and cursor-based pagination state for an object search page.
41
- *
42
- * ## State model
43
- * Local React state is the primary driver for instant UI updates.
44
- * URL search params act as the durable source of truth so that a page
45
- * refresh or shared link restores the same view. Changes are synced to
46
- * the URL via a debounced write (300 ms) to avoid excessive history entries.
47
- *
48
- * ## Return shape
49
- * Returns memoized groups so each group's reference is stable unless its
50
- * contents change — safe to pass directly as props to `React.memo` children.
51
- *
52
- * - `filters` — active filter values + set/remove callbacks
53
- * - `sort` — current sort state + set callback
54
- * - `query` — derived `where` / `orderBy` objects ready for the API
55
- * - `pagination` — page size, page index, cursor, and navigation callbacks
56
- * - `resetAll` — clears all filters, sort, and pagination in one call
57
- */
58
- export function useObjectSearchParams<TFilter, TOrderBy>(
59
- filterConfigs: FilterFieldConfig[],
60
- _sortConfigs?: SortFieldConfig[],
61
- paginationConfig?: PaginationConfig,
62
- ) {
63
- const defaultPageSize = paginationConfig?.defaultPageSize ?? 10;
64
- const validPageSizes = useMemo(
65
- () => paginationConfig?.validPageSizes ?? [defaultPageSize],
66
- [paginationConfig?.validPageSizes, defaultPageSize],
67
- );
68
- const [searchParams, setSearchParams] = useSearchParams();
69
-
70
- // Seed local state from URL on initial load
71
- const initial = useMemo(
72
- () => searchParamsToFilters(searchParams, filterConfigs),
73
- // Only run on mount — local state takes over after that, no deps needed
74
- // eslint-disable-next-line react-hooks/exhaustive-deps
75
- [],
76
- );
77
-
78
- const [filters, setFilters] = useState<ActiveFilterValue[]>(initial.filters);
79
- const [sort, setLocalSort] = useState<SortState | null>(initial.sort);
80
-
81
- // Pagination — cursor-based with a stack to support "previous page" navigation.
82
- const getValidPageSize = useCallback(
83
- (size: number) => (validPageSizes.includes(size) ? size : defaultPageSize),
84
- [validPageSizes, defaultPageSize],
85
- );
86
-
87
- const [pageSize, setPageSizeState] = useState<number>(
88
- getValidPageSize(initial.pageSize ?? defaultPageSize),
89
- );
90
- const [pageIndex, setPageIndex] = useState(initial.pageIndex);
91
- const [afterCursor, setAfterCursor] = useState<string | undefined>(undefined);
92
- const cursorStackRef = useRef<string[]>([]);
93
-
94
- // Debounced URL sync — keeps URL in sync without blocking the UI
95
- const syncToUrl = useCallback(
96
- (
97
- nextFilters: ActiveFilterValue[],
98
- nextSort: SortState | null,
99
- nextPageSize?: number,
100
- nextPageIndex?: number,
101
- ) => {
102
- const params = filtersToSearchParams(nextFilters, nextSort, nextPageSize, nextPageIndex);
103
- setSearchParams(params, { replace: true });
104
- },
105
- [setSearchParams],
106
- );
107
-
108
- const debouncedSyncRef = useRef(debounce(syncToUrl, URL_SYNC_DEBOUNCE_MS));
109
- useEffect(() => {
110
- debouncedSyncRef.current = debounce(syncToUrl, URL_SYNC_DEBOUNCE_MS);
111
- }, [syncToUrl]);
112
-
113
- // Snapshot ref — lets callbacks read the latest state without being
114
- // recreated on every render (avoids infinite useCallback chains).
115
- const stateRef = useRef({ filters, sort, pageSize, pageIndex });
116
- useEffect(() => {
117
- stateRef.current = { filters, sort, pageSize, pageIndex };
118
- });
119
-
120
- // Any filter/sort change resets pagination to the first page.
121
- const resetPagination = useCallback(() => {
122
- setPageIndex(0);
123
- setAfterCursor(undefined);
124
- cursorStackRef.current = [];
125
- }, []);
126
-
127
- // -- Filter callbacks -------------------------------------------------------
128
-
129
- const setFilter = useCallback(
130
- (field: string, value: ActiveFilterValue | undefined) => {
131
- const { sort: s, pageSize: ps } = stateRef.current;
132
- setFilters((prev) => {
133
- const next = prev.filter((f) => f.field !== field);
134
- if (value) next.push(value);
135
- debouncedSyncRef.current(next, s, ps);
136
- return next;
137
- });
138
- resetPagination();
139
- },
140
- [resetPagination],
141
- );
142
-
143
- const removeFilter = useCallback(
144
- (field: string) => {
145
- const { sort: s, pageSize: ps } = stateRef.current;
146
- setFilters((prev) => {
147
- const next = prev.filter((f) => f.field !== field);
148
- debouncedSyncRef.current(next, s, ps);
149
- return next;
150
- });
151
- resetPagination();
152
- },
153
- [resetPagination],
154
- );
155
-
156
- // -- Sort callback ----------------------------------------------------------
157
-
158
- const setSort = useCallback(
159
- (nextSort: SortState | null) => {
160
- const { filters: f, pageSize: ps } = stateRef.current;
161
- setLocalSort(nextSort);
162
- debouncedSyncRef.current(f, nextSort, ps);
163
- resetPagination();
164
- },
165
- [resetPagination],
166
- );
167
-
168
- // -- Reset ------------------------------------------------------------------
169
-
170
- const resetAll = useCallback(() => {
171
- setFilters([]);
172
- setLocalSort(null);
173
- resetPagination();
174
- syncToUrl([], null, defaultPageSize, 0);
175
- setPageSizeState(defaultPageSize);
176
- }, [syncToUrl, resetPagination, defaultPageSize]);
177
-
178
- // -- Pagination callbacks ---------------------------------------------------
179
- // Uses a cursor stack to track visited pages. "Next" pushes the current
180
- // endCursor onto the stack; "Previous" pops it to restore the prior cursor.
181
-
182
- const goToNextPage = useCallback((endCursor: string) => {
183
- cursorStackRef.current = [...cursorStackRef.current, endCursor];
184
- setAfterCursor(endCursor);
185
- setPageIndex((prev) => {
186
- const nextIndex = prev + 1;
187
- const { filters: f, sort: s, pageSize: ps } = stateRef.current;
188
- debouncedSyncRef.current(f, s, ps, nextIndex);
189
- return nextIndex;
190
- });
191
- }, []);
192
-
193
- const goToPreviousPage = useCallback(() => {
194
- const stack = cursorStackRef.current;
195
- const next = stack.slice(0, -1);
196
- cursorStackRef.current = next;
197
- setAfterCursor(next.length > 0 ? next[next.length - 1] : undefined);
198
- setPageIndex((prev) => {
199
- const nextIndex = Math.max(0, prev - 1);
200
- const { filters: f, sort: s, pageSize: ps } = stateRef.current;
201
- debouncedSyncRef.current(f, s, ps, nextIndex);
202
- return nextIndex;
203
- });
204
- }, []);
205
-
206
- const setPageSize = useCallback(
207
- (newSize: number) => {
208
- const validated = getValidPageSize(newSize);
209
- const { filters: f, sort: s } = stateRef.current;
210
- setPageSizeState(validated);
211
- resetPagination();
212
- debouncedSyncRef.current(f, s, validated);
213
- },
214
- [resetPagination, getValidPageSize],
215
- );
216
-
217
- // -- Derived query objects ---------------------------------------------------
218
- // Translate local filter/sort state into API-ready `where` and `orderBy`.
219
-
220
- const where = useMemo(
221
- () => buildFilter<TFilter>(filters, filterConfigs),
222
- [filters, filterConfigs],
223
- );
224
-
225
- const orderBy = useMemo(() => buildOrderBy<TOrderBy>(sort), [sort]);
226
-
227
- // -- Memoized return groups -------------------------------------------------
228
- // Each group is individually memoized so its object reference stays stable
229
- // unless the contained values change. This makes it safe to pass a group
230
- // (e.g. `pagination`) directly as props to a React.memo child without
231
- // causing unnecessary re-renders.
232
-
233
- const filtersGroup = useMemo(
234
- () => ({ active: filters, set: setFilter, remove: removeFilter }),
235
- [filters, setFilter, removeFilter],
236
- );
237
-
238
- const sortGroup = useMemo(() => ({ current: sort, set: setSort }), [sort, setSort]);
239
-
240
- const query = useMemo(() => ({ where, orderBy }), [where, orderBy]);
241
-
242
- const pagination = useMemo(
243
- () => ({ pageSize, pageIndex, afterCursor, setPageSize, goToNextPage, goToPreviousPage }),
244
- [pageSize, pageIndex, afterCursor, setPageSize, goToNextPage, goToPreviousPage],
245
- );
246
-
247
- return {
248
- filters: filtersGroup,
249
- sort: sortGroup,
250
- query,
251
- pagination,
252
- resetAll,
253
- };
254
- }
@@ -1,25 +0,0 @@
1
- /** Default debounce delay for keystroke-driven filter inputs (search, text, numeric). */
2
- export const FILTER_DEBOUNCE_MS = 300;
3
-
4
- /**
5
- * Creates a debounced version of the provided function.
6
- *
7
- * Each call to the returned function resets the internal timer. The wrapped
8
- * function is only invoked once the timer expires without being reset. This
9
- * makes it ideal for rate-limiting high-frequency events like input changes.
10
- *
11
- * @typeParam T - The function signature to debounce.
12
- * @param fn - The function to debounce.
13
- * @param ms - The debounce delay in milliseconds.
14
- * @returns A new function with the same signature that delays execution.
15
- */
16
- export function debounce<T extends (...args: any[]) => void>(
17
- fn: T,
18
- ms: number,
19
- ): (...args: Parameters<T>) => void {
20
- let timer: ReturnType<typeof setTimeout> | undefined;
21
- return (...args: Parameters<T>) => {
22
- clearTimeout(timer);
23
- timer = setTimeout(() => fn(...args), ms);
24
- };
25
- }