@salesforce/templates 66.5.4 → 66.5.6

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 (424) hide show
  1. package/lib/templates/project/.forceignore +3 -1
  2. package/lib/templates/project/reactb2e/AGENT.md +12 -2
  3. package/lib/templates/project/reactb2e/CHANGELOG.md +401 -0
  4. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/.forceignore +15 -0
  5. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/codegen.yml +1 -0
  6. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/eslint.config.js +44 -27
  7. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/index.html +0 -1
  8. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/package.json +7 -11
  9. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/accountSearchService.ts +46 -0
  10. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/distinctAccountIndustries.graphql +19 -0
  11. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/distinctAccountTypes.graphql +19 -0
  12. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/getAccountDetail.graphql +121 -0
  13. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/searchAccounts.graphql +51 -0
  14. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/pages/AccountObjectDetailPage.tsx +357 -0
  15. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/pages/AccountSearch.tsx +275 -0
  16. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/pages/Home.tsx +34 -0
  17. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +84 -0
  18. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +89 -0
  19. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/FilterPanel.tsx +127 -0
  20. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ObjectBreadcrumb.tsx +66 -0
  21. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +151 -0
  22. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +41 -0
  23. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +143 -0
  24. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +94 -0
  25. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +165 -0
  26. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +78 -0
  27. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +106 -0
  28. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +102 -0
  29. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +40 -0
  30. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +97 -0
  31. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +77 -0
  32. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useAsyncData.ts +53 -0
  33. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useCachedAsyncData.ts +183 -0
  34. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +225 -0
  35. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +22 -0
  36. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/fieldUtils.ts +29 -0
  37. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +372 -0
  38. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +38 -0
  39. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +11260 -0
  40. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/app.tsx +4 -1
  41. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/appLayout.tsx +1 -1
  42. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.tsx +33 -5
  43. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/alerts/status-alert.tsx +1 -1
  44. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/badge.tsx +48 -0
  45. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/breadcrumb.tsx +109 -0
  46. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/calendar.tsx +232 -0
  47. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/checkbox.tsx +32 -0
  48. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/collapsible.tsx +33 -0
  49. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +127 -0
  50. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/popover.tsx +89 -0
  51. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/components/ui/sonner.tsx +20 -0
  52. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/index.ts +3 -117
  53. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/pages/Home.tsx +10 -11
  54. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/pages/TestAccPage.tsx +1 -1
  55. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/routes.tsx +8 -20
  56. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/types/conversation.ts +14 -4
  57. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/tsconfig.json +7 -1
  58. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/vite.config.ts +17 -13
  59. package/lib/templates/project/reactb2e/_r_/skills/{webapp-react-data-visualization → building-data-visualization}/SKILL.md +3 -3
  60. package/lib/templates/project/reactb2e/_r_/skills/building-data-visualization/implementation/bar-line-chart.md +316 -0
  61. package/lib/templates/project/{reactb2x/_r_/skills/webapp-react-data-visualization → reactb2e/_r_/skills/building-data-visualization}/implementation/donut-chart.md +1 -1
  62. package/lib/templates/project/{reactb2x/_r_/skills/webapp-react → reactb2e/_r_/skills/building-react-components}/SKILL.md +21 -5
  63. package/lib/templates/project/reactb2e/_r_/skills/{webapp-csp-trusted-sites → configuring-csp-trusted-sites}/SKILL.md +1 -1
  64. package/lib/templates/project/{reactb2x/_r_/webapp-webapplication.md → reactb2e/_r_/skills/configuring-webapp-metadata/SKILL.md} +2 -3
  65. package/lib/templates/project/reactb2e/_r_/{webapp.md → skills/creating-webapp/SKILL.md} +46 -4
  66. package/lib/templates/project/reactb2e/_r_/skills/deploying-to-salesforce/SKILL.md +226 -0
  67. package/lib/templates/project/reactb2e/_r_/skills/{feature-react-file-upload-file-upload → implementing-file-upload}/SKILL.md +1 -1
  68. package/lib/templates/project/{reactb2x/_r_/skills/webapp-features → reactb2e/_r_/skills/installing-webapp-features}/SKILL.md +3 -3
  69. package/lib/templates/project/reactb2e/_r_/skills/managing-agentforce-conversation-client/SKILL.md +186 -0
  70. package/lib/templates/project/reactb2e/_r_/skills/managing-agentforce-conversation-client/references/constraints.md +134 -0
  71. package/lib/templates/project/reactb2e/_r_/skills/managing-agentforce-conversation-client/references/examples.md +132 -0
  72. package/lib/templates/project/reactb2e/_r_/skills/managing-agentforce-conversation-client/references/style-tokens.md +101 -0
  73. package/lib/templates/project/reactb2e/_r_/skills/managing-agentforce-conversation-client/references/troubleshooting.md +57 -0
  74. package/lib/templates/project/reactb2e/_r_/skills/using-salesforce-data/SKILL.md +363 -0
  75. package/lib/templates/project/reactb2e/_r_/skills/using-salesforce-data/graphql-search.sh +139 -0
  76. package/lib/templates/project/reactb2e/_r_/webapp-data.md +353 -0
  77. package/lib/templates/project/reactb2e/_r_/webapp-ui.md +16 -0
  78. package/lib/templates/project/reactb2e/eslint.config.js +7 -0
  79. package/lib/templates/project/reactb2e/package-lock.json +9995 -0
  80. package/lib/templates/project/reactb2e/package.json +12 -11
  81. package/lib/templates/project/reactb2e/scripts/setup-cli.mjs +61 -31
  82. package/lib/templates/project/reactb2e/scripts/sf-project-setup.mjs +66 -0
  83. package/lib/templates/project/reactb2x/AGENT.md +12 -2
  84. package/lib/templates/project/reactb2x/CHANGELOG.md +401 -0
  85. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/.forceignore +15 -0
  86. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/codegen.yml +1 -0
  87. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/eslint.config.js +44 -27
  88. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/index.html +0 -1
  89. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/package.json +8 -11
  90. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/accountSearchService.ts +46 -0
  91. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/distinctAccountIndustries.graphql +19 -0
  92. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/distinctAccountTypes.graphql +19 -0
  93. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/getAccountDetail.graphql +121 -0
  94. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/api/query/searchAccounts.graphql +51 -0
  95. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/pages/AccountObjectDetailPage.tsx +357 -0
  96. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/pages/AccountSearch.tsx +275 -0
  97. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/__examples__/pages/Home.tsx +34 -0
  98. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +84 -0
  99. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +89 -0
  100. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/FilterPanel.tsx +127 -0
  101. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ObjectBreadcrumb.tsx +66 -0
  102. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +151 -0
  103. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +41 -0
  104. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +143 -0
  105. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +94 -0
  106. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +165 -0
  107. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +78 -0
  108. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +106 -0
  109. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +102 -0
  110. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +40 -0
  111. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +97 -0
  112. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +77 -0
  113. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useAsyncData.ts +53 -0
  114. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useCachedAsyncData.ts +183 -0
  115. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +225 -0
  116. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +22 -0
  117. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/fieldUtils.ts +29 -0
  118. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +372 -0
  119. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +38 -0
  120. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/api/userProfileApi.ts +13 -13
  121. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/layouts/privateRouteLayout.tsx +10 -2
  122. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/ChangePassword.tsx +2 -2
  123. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/ForgotPassword.tsx +2 -2
  124. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Login.tsx +2 -2
  125. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Profile.tsx +26 -4
  126. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Register.tsx +2 -2
  127. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/ResetPassword.tsx +2 -2
  128. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/sessionTimeout/SessionTimeoutValidator.tsx +8 -16
  129. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/authentication/sessionTimeout/sessionTimeService.ts +30 -42
  130. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +11260 -0
  131. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/app.tsx +3 -1
  132. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/alerts/status-alert.tsx +1 -1
  133. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/badge.tsx +48 -0
  134. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/breadcrumb.tsx +109 -0
  135. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/calendar.tsx +232 -0
  136. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/checkbox.tsx +32 -0
  137. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/collapsible.tsx +33 -0
  138. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +127 -0
  139. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/popover.tsx +89 -0
  140. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/components/ui/sonner.tsx +20 -0
  141. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/pages/Home.tsx +10 -11
  142. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/routes.tsx +9 -21
  143. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/tsconfig.json +7 -1
  144. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/vite.config.ts +17 -13
  145. package/lib/templates/project/reactb2x/_p_/_m_/networks/appreacttemplateb2x.network +1 -1
  146. package/lib/templates/project/reactb2x/_r_/skills/{webapp-react-data-visualization → building-data-visualization}/SKILL.md +3 -3
  147. package/lib/templates/project/reactb2x/_r_/skills/building-data-visualization/implementation/bar-line-chart.md +316 -0
  148. package/lib/templates/project/{reactb2e/_r_/skills/webapp-react-data-visualization → reactb2x/_r_/skills/building-data-visualization}/implementation/donut-chart.md +1 -1
  149. package/lib/templates/project/{reactb2e/_r_/skills/webapp-react → reactb2x/_r_/skills/building-react-components}/SKILL.md +21 -5
  150. package/lib/templates/project/reactb2x/_r_/skills/{webapp-csp-trusted-sites → configuring-csp-trusted-sites}/SKILL.md +1 -1
  151. package/lib/templates/project/{reactb2e/_r_/webapp-webapplication.md → reactb2x/_r_/skills/configuring-webapp-metadata/SKILL.md} +2 -3
  152. package/lib/templates/project/reactb2x/_r_/{webapp.md → skills/creating-webapp/SKILL.md} +46 -4
  153. package/lib/templates/project/reactb2x/_r_/skills/deploying-to-salesforce/SKILL.md +226 -0
  154. package/lib/templates/project/reactb2x/_r_/skills/{feature-react-file-upload-file-upload → implementing-file-upload}/SKILL.md +1 -1
  155. package/lib/templates/project/{reactb2e/_r_/skills/webapp-features → reactb2x/_r_/skills/installing-webapp-features}/SKILL.md +3 -3
  156. package/lib/templates/project/reactb2x/_r_/skills/managing-agentforce-conversation-client/SKILL.md +186 -0
  157. package/lib/templates/project/reactb2x/_r_/skills/managing-agentforce-conversation-client/references/constraints.md +134 -0
  158. package/lib/templates/project/reactb2x/_r_/skills/managing-agentforce-conversation-client/references/examples.md +132 -0
  159. package/lib/templates/project/reactb2x/_r_/skills/managing-agentforce-conversation-client/references/style-tokens.md +101 -0
  160. package/lib/templates/project/reactb2x/_r_/skills/managing-agentforce-conversation-client/references/troubleshooting.md +57 -0
  161. package/lib/templates/project/reactb2x/_r_/skills/using-salesforce-data/SKILL.md +363 -0
  162. package/lib/templates/project/reactb2x/_r_/skills/using-salesforce-data/graphql-search.sh +139 -0
  163. package/lib/templates/project/reactb2x/_r_/webapp-data.md +353 -0
  164. package/lib/templates/project/reactb2x/_r_/webapp-ui.md +16 -0
  165. package/lib/templates/project/reactb2x/eslint.config.js +7 -0
  166. package/lib/templates/project/reactb2x/package-lock.json +9995 -0
  167. package/lib/templates/project/reactb2x/package.json +12 -11
  168. package/lib/templates/project/reactb2x/scripts/setup-cli.mjs +61 -31
  169. package/lib/templates/project/reactb2x/scripts/sf-project-setup.mjs +66 -0
  170. package/lib/templates/webapplication/reactbasic/.forceignore +15 -0
  171. package/lib/templates/webapplication/reactbasic/codegen.yml +1 -0
  172. package/lib/templates/webapplication/reactbasic/eslint.config.js +44 -27
  173. package/lib/templates/webapplication/reactbasic/index.html +0 -1
  174. package/lib/templates/webapplication/reactbasic/package.json +6 -3
  175. package/lib/templates/webapplication/reactbasic/src/app.tsx +4 -1
  176. package/lib/templates/webapplication/reactbasic/src/components/alerts/status-alert.tsx +1 -1
  177. package/lib/templates/webapplication/reactbasic/src/components/ui/badge.tsx +48 -0
  178. package/lib/templates/webapplication/reactbasic/src/components/ui/breadcrumb.tsx +109 -0
  179. package/lib/templates/webapplication/reactbasic/src/components/ui/calendar.tsx +232 -0
  180. package/lib/templates/webapplication/reactbasic/src/components/ui/checkbox.tsx +32 -0
  181. package/lib/templates/webapplication/reactbasic/src/components/ui/collapsible.tsx +33 -0
  182. package/lib/templates/webapplication/reactbasic/src/components/ui/datePicker.tsx +127 -0
  183. package/lib/templates/webapplication/reactbasic/src/components/ui/popover.tsx +89 -0
  184. package/lib/templates/webapplication/reactbasic/src/components/ui/sonner.tsx +20 -0
  185. package/lib/templates/webapplication/reactbasic/tsconfig.json +7 -1
  186. package/lib/templates/webapplication/reactbasic/vite.config.ts +17 -13
  187. package/lib/utils/template-placeholders.js +7 -0
  188. package/lib/utils/template-placeholders.js.map +1 -1
  189. package/lib/utils/webappTemplateUtils.d.ts +3 -1
  190. package/lib/utils/webappTemplateUtils.js +4 -1
  191. package/lib/utils/webappTemplateUtils.js.map +1 -1
  192. package/package.json +6 -6
  193. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailFields.tsx +0 -55
  194. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailForm.tsx +0 -146
  195. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailHeader.tsx +0 -34
  196. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailLayoutSections.tsx +0 -80
  197. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/Section.tsx +0 -108
  198. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/SectionRow.tsx +0 -20
  199. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/UiApiDetailForm.tsx +0 -140
  200. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FieldValueDisplay.tsx +0 -73
  201. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedAddress.tsx +0 -29
  202. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedEmail.tsx +0 -17
  203. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedPhone.tsx +0 -24
  204. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedText.tsx +0 -11
  205. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedUrl.tsx +0 -29
  206. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FilterField.tsx +0 -54
  207. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FilterInput.tsx +0 -55
  208. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FilterSelect.tsx +0 -72
  209. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FiltersPanel.tsx +0 -380
  210. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/forms/filters-form.tsx +0 -114
  211. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/forms/submit-button.tsx +0 -47
  212. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/GlobalSearchInput.tsx +0 -114
  213. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/ResultCardFields.tsx +0 -71
  214. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchHeader.tsx +0 -31
  215. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchPagination.tsx +0 -144
  216. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchResultCard.tsx +0 -136
  217. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchResultsPanel.tsx +0 -197
  218. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/shared/LoadingFallback.tsx +0 -61
  219. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/objectDetailService.ts +0 -102
  220. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/objectInfoGraphQLService.ts +0 -137
  221. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/objectInfoService.ts +0 -95
  222. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/recordListGraphQLService.ts +0 -364
  223. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/constants.ts +0 -39
  224. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/filters/FilterInput.tsx +0 -55
  225. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/filters/FilterSelect.tsx +0 -72
  226. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/form.tsx +0 -209
  227. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useObjectInfoBatch.ts +0 -65
  228. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useObjectSearchData.ts +0 -174
  229. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useRecordDetailLayout.ts +0 -137
  230. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useRecordListGraphQL.ts +0 -135
  231. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/pages/DetailPage.tsx +0 -109
  232. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/pages/GlobalSearch.tsx +0 -229
  233. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/filters/filters.ts +0 -121
  234. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/filters/picklist.ts +0 -6
  235. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/objectInfo/objectInfo.ts +0 -49
  236. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/recordDetail/recordDetail.ts +0 -61
  237. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/schema.d.ts +0 -200
  238. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/search/searchResults.ts +0 -229
  239. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/apiUtils.ts +0 -59
  240. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/cacheUtils.ts +0 -76
  241. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/debounce.ts +0 -89
  242. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/fieldUtils.ts +0 -354
  243. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/fieldValueExtractor.ts +0 -67
  244. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/filterUtils.ts +0 -32
  245. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/formDataTransformUtils.ts +0 -260
  246. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/formUtils.ts +0 -142
  247. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/graphQLNodeFieldUtils.ts +0 -186
  248. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/graphQLObjectInfoAdapter.ts +0 -77
  249. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/graphQLRecordAdapter.ts +0 -90
  250. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/layoutTransformUtils.ts +0 -236
  251. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/linkUtils.ts +0 -14
  252. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/paginationUtils.ts +0 -49
  253. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/recordUtils.ts +0 -159
  254. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/sanitizationUtils.ts +0 -49
  255. package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +0 -1
  256. package/lib/templates/project/reactb2e/_r_/features/feature-graphql-graphql-data-access-rule.md +0 -470
  257. package/lib/templates/project/reactb2e/_r_/features/feature-react-agentforce-conversation-client-embedded-agent-rule.md +0 -18
  258. package/lib/templates/project/reactb2e/_r_/features/feature-react-chart-analytics-charts-rule.md +0 -27
  259. package/lib/templates/project/reactb2e/_r_/skills/_k_/SKILL.md +0 -148
  260. package/lib/templates/project/reactb2e/_r_/skills/_k_/docs/embed-examples.md +0 -192
  261. package/lib/templates/project/reactb2e/_r_/skills/_k_/docs/troubleshooting.md +0 -51
  262. package/lib/templates/project/reactb2e/_r_/skills/feature-graphql-graphql-data-access/SKILL.md +0 -155
  263. package/lib/templates/project/reactb2e/_r_/skills/feature-graphql-graphql-data-access/docs/explore-schema.md +0 -256
  264. package/lib/templates/project/reactb2e/_r_/skills/feature-graphql-graphql-data-access/docs/generate-mutation-query.md +0 -228
  265. package/lib/templates/project/reactb2e/_r_/skills/feature-graphql-graphql-data-access/docs/generate-read-query.md +0 -202
  266. package/lib/templates/project/reactb2e/_r_/skills/feature-graphql-graphql-data-access/docs/shared-schema.graphqls +0 -1150
  267. package/lib/templates/project/reactb2e/_r_/skills/feature-micro-frontend-micro-frontend/SKILL.md +0 -137
  268. package/lib/templates/project/reactb2e/_r_/skills/feature-react-chart-analytics-charts/SKILL.md +0 -41
  269. package/lib/templates/project/reactb2e/_r_/skills/feature-react-chart-analytics-charts/docs/schema-mapping.md +0 -4
  270. package/lib/templates/project/reactb2e/_r_/skills/webapp-react-interactive-map/SKILL.md +0 -92
  271. package/lib/templates/project/reactb2e/_r_/skills/webapp-react-interactive-map/implementation/geocoding.md +0 -245
  272. package/lib/templates/project/reactb2e/_r_/skills/webapp-react-interactive-map/implementation/leaflet-map.md +0 -279
  273. package/lib/templates/project/reactb2e/_r_/skills/webapp-react-weather-widget/SKILL.md +0 -65
  274. package/lib/templates/project/reactb2e/_r_/skills/webapp-react-weather-widget/implementation/weather-hook.md +0 -258
  275. package/lib/templates/project/reactb2e/_r_/skills/webapp-react-weather-widget/implementation/weather-ui.md +0 -216
  276. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/SKILL.md +0 -271
  277. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/charts.csv +0 -26
  278. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/colors.csv +0 -97
  279. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/icons.csv +0 -101
  280. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/landing.csv +0 -31
  281. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/products.csv +0 -97
  282. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/react-performance.csv +0 -45
  283. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/stacks/html-tailwind.csv +0 -56
  284. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/stacks/react.csv +0 -54
  285. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/stacks/shadcn.csv +0 -61
  286. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/styles.csv +0 -68
  287. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/typography.csv +0 -58
  288. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/ui-reasoning.csv +0 -101
  289. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/ux-guidelines.csv +0 -100
  290. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/data/web-interface.csv +0 -31
  291. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/scripts/core.js +0 -255
  292. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/scripts/design_system.js +0 -861
  293. package/lib/templates/project/reactb2e/_r_/skills/webapp-ui-ux/scripts/search.js +0 -98
  294. package/lib/templates/project/reactb2e/_r_/skills/webapp-unsplash-images/SKILL.md +0 -71
  295. package/lib/templates/project/reactb2e/_r_/skills/webapp-unsplash-images/implementation/usage.md +0 -159
  296. package/lib/templates/project/reactb2e/_r_/webapp-cli-commands.md +0 -88
  297. package/lib/templates/project/reactb2e/_r_/webapp-react-code-quality.md +0 -136
  298. package/lib/templates/project/reactb2e/_r_/webapp-react-typescript.md +0 -205
  299. package/lib/templates/project/reactb2e/_r_/webapp-react.md +0 -202
  300. package/lib/templates/project/reactb2e/_r_/webapp-skills-first.md +0 -26
  301. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailFields.tsx +0 -55
  302. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailForm.tsx +0 -146
  303. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailHeader.tsx +0 -34
  304. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/DetailLayoutSections.tsx +0 -80
  305. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/Section.tsx +0 -108
  306. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/SectionRow.tsx +0 -20
  307. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/UiApiDetailForm.tsx +0 -140
  308. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FieldValueDisplay.tsx +0 -73
  309. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedAddress.tsx +0 -29
  310. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedEmail.tsx +0 -17
  311. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedPhone.tsx +0 -24
  312. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedText.tsx +0 -11
  313. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/_det_/_fmt_/FormattedUrl.tsx +0 -29
  314. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FilterField.tsx +0 -54
  315. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FilterInput.tsx +0 -55
  316. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FilterSelect.tsx +0 -72
  317. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/filters/FiltersPanel.tsx +0 -380
  318. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/forms/filters-form.tsx +0 -114
  319. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/forms/submit-button.tsx +0 -47
  320. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/GlobalSearchInput.tsx +0 -114
  321. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/ResultCardFields.tsx +0 -71
  322. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchHeader.tsx +0 -31
  323. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchPagination.tsx +0 -144
  324. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchResultCard.tsx +0 -136
  325. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/search/SearchResultsPanel.tsx +0 -197
  326. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/_c_/shared/LoadingFallback.tsx +0 -61
  327. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/objectDetailService.ts +0 -102
  328. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/objectInfoGraphQLService.ts +0 -137
  329. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/objectInfoService.ts +0 -95
  330. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/api/recordListGraphQLService.ts +0 -364
  331. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/constants.ts +0 -39
  332. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/filters/FilterInput.tsx +0 -55
  333. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/filters/FilterSelect.tsx +0 -72
  334. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/form.tsx +0 -209
  335. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useObjectInfoBatch.ts +0 -65
  336. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useObjectSearchData.ts +0 -174
  337. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useRecordDetailLayout.ts +0 -137
  338. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/hooks/useRecordListGraphQL.ts +0 -135
  339. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/pages/DetailPage.tsx +0 -109
  340. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/pages/GlobalSearch.tsx +0 -229
  341. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/filters/filters.ts +0 -121
  342. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/filters/picklist.ts +0 -6
  343. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/objectInfo/objectInfo.ts +0 -49
  344. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/recordDetail/recordDetail.ts +0 -61
  345. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/schema.d.ts +0 -200
  346. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/types/search/searchResults.ts +0 -229
  347. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/apiUtils.ts +0 -59
  348. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/cacheUtils.ts +0 -76
  349. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/debounce.ts +0 -89
  350. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/fieldUtils.ts +0 -354
  351. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/fieldValueExtractor.ts +0 -67
  352. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/filterUtils.ts +0 -32
  353. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/formDataTransformUtils.ts +0 -260
  354. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/formUtils.ts +0 -142
  355. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/graphQLNodeFieldUtils.ts +0 -186
  356. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/graphQLObjectInfoAdapter.ts +0 -77
  357. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/graphQLRecordAdapter.ts +0 -90
  358. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/layoutTransformUtils.ts +0 -236
  359. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/linkUtils.ts +0 -14
  360. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/paginationUtils.ts +0 -49
  361. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/recordUtils.ts +0 -159
  362. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/_f_/_gs_/utils/sanitizationUtils.ts +0 -49
  363. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/src/index.ts +0 -120
  364. package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +0 -1
  365. package/lib/templates/project/reactb2x/_r_/features/feature-graphql-graphql-data-access-rule.md +0 -470
  366. package/lib/templates/project/reactb2x/_r_/features/feature-react-agentforce-conversation-client-embedded-agent-rule.md +0 -18
  367. package/lib/templates/project/reactb2x/_r_/features/feature-react-chart-analytics-charts-rule.md +0 -27
  368. package/lib/templates/project/reactb2x/_r_/skills/_k_/SKILL.md +0 -148
  369. package/lib/templates/project/reactb2x/_r_/skills/_k_/docs/embed-examples.md +0 -192
  370. package/lib/templates/project/reactb2x/_r_/skills/_k_/docs/troubleshooting.md +0 -51
  371. package/lib/templates/project/reactb2x/_r_/skills/feature-graphql-graphql-data-access/SKILL.md +0 -155
  372. package/lib/templates/project/reactb2x/_r_/skills/feature-graphql-graphql-data-access/docs/explore-schema.md +0 -256
  373. package/lib/templates/project/reactb2x/_r_/skills/feature-graphql-graphql-data-access/docs/generate-mutation-query.md +0 -228
  374. package/lib/templates/project/reactb2x/_r_/skills/feature-graphql-graphql-data-access/docs/generate-read-query.md +0 -202
  375. package/lib/templates/project/reactb2x/_r_/skills/feature-graphql-graphql-data-access/docs/shared-schema.graphqls +0 -1150
  376. package/lib/templates/project/reactb2x/_r_/skills/feature-micro-frontend-micro-frontend/SKILL.md +0 -137
  377. package/lib/templates/project/reactb2x/_r_/skills/feature-react-chart-analytics-charts/SKILL.md +0 -41
  378. package/lib/templates/project/reactb2x/_r_/skills/feature-react-chart-analytics-charts/docs/schema-mapping.md +0 -4
  379. package/lib/templates/project/reactb2x/_r_/skills/webapp-react-interactive-map/SKILL.md +0 -92
  380. package/lib/templates/project/reactb2x/_r_/skills/webapp-react-interactive-map/implementation/geocoding.md +0 -245
  381. package/lib/templates/project/reactb2x/_r_/skills/webapp-react-interactive-map/implementation/leaflet-map.md +0 -279
  382. package/lib/templates/project/reactb2x/_r_/skills/webapp-react-weather-widget/SKILL.md +0 -65
  383. package/lib/templates/project/reactb2x/_r_/skills/webapp-react-weather-widget/implementation/weather-hook.md +0 -258
  384. package/lib/templates/project/reactb2x/_r_/skills/webapp-react-weather-widget/implementation/weather-ui.md +0 -216
  385. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/SKILL.md +0 -271
  386. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/charts.csv +0 -26
  387. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/colors.csv +0 -97
  388. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/icons.csv +0 -101
  389. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/landing.csv +0 -31
  390. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/products.csv +0 -97
  391. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/react-performance.csv +0 -45
  392. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/stacks/html-tailwind.csv +0 -56
  393. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/stacks/react.csv +0 -54
  394. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/stacks/shadcn.csv +0 -61
  395. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/styles.csv +0 -68
  396. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/typography.csv +0 -58
  397. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/ui-reasoning.csv +0 -101
  398. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/ux-guidelines.csv +0 -100
  399. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/data/web-interface.csv +0 -31
  400. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/scripts/core.js +0 -255
  401. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/scripts/design_system.js +0 -861
  402. package/lib/templates/project/reactb2x/_r_/skills/webapp-ui-ux/scripts/search.js +0 -98
  403. package/lib/templates/project/reactb2x/_r_/skills/webapp-unsplash-images/SKILL.md +0 -71
  404. package/lib/templates/project/reactb2x/_r_/skills/webapp-unsplash-images/implementation/usage.md +0 -159
  405. package/lib/templates/project/reactb2x/_r_/webapp-cli-commands.md +0 -88
  406. package/lib/templates/project/reactb2x/_r_/webapp-react-code-quality.md +0 -136
  407. package/lib/templates/project/reactb2x/_r_/webapp-react-typescript.md +0 -205
  408. package/lib/templates/project/reactb2x/_r_/webapp-react.md +0 -202
  409. package/lib/templates/project/reactb2x/_r_/webapp-skills-first.md +0 -26
  410. /package/lib/templates/project/reactb2e/_p_/_m_/_w_/_a_/{src/components.json → components.json} +0 -0
  411. /package/lib/templates/project/reactb2e/_r_/skills/{webapp-react-data-visualization → building-data-visualization}/implementation/dashboard-layout.md +0 -0
  412. /package/lib/templates/project/reactb2e/_r_/skills/{webapp-react-data-visualization → building-data-visualization}/implementation/stat-card.md +0 -0
  413. /package/lib/templates/project/reactb2e/_r_/skills/{webapp-react → building-react-components}/implementation/component.md +0 -0
  414. /package/lib/templates/project/reactb2e/_r_/skills/{webapp-react → building-react-components}/implementation/header-footer.md +0 -0
  415. /package/lib/templates/project/reactb2e/_r_/skills/{webapp-react → building-react-components}/implementation/page.md +0 -0
  416. /package/lib/templates/project/reactb2e/_r_/skills/{webapp-csp-trusted-sites → configuring-csp-trusted-sites}/implementation/metadata-format.md +0 -0
  417. /package/lib/templates/project/reactb2x/_p_/_m_/_w_/_a_/{src/components.json → components.json} +0 -0
  418. /package/lib/templates/project/reactb2x/_r_/skills/{webapp-react-data-visualization → building-data-visualization}/implementation/dashboard-layout.md +0 -0
  419. /package/lib/templates/project/reactb2x/_r_/skills/{webapp-react-data-visualization → building-data-visualization}/implementation/stat-card.md +0 -0
  420. /package/lib/templates/project/reactb2x/_r_/skills/{webapp-react → building-react-components}/implementation/component.md +0 -0
  421. /package/lib/templates/project/reactb2x/_r_/skills/{webapp-react → building-react-components}/implementation/header-footer.md +0 -0
  422. /package/lib/templates/project/reactb2x/_r_/skills/{webapp-react → building-react-components}/implementation/page.md +0 -0
  423. /package/lib/templates/project/reactb2x/_r_/skills/{webapp-csp-trusted-sites → configuring-csp-trusted-sites}/implementation/metadata-format.md +0 -0
  424. /package/lib/templates/webapplication/reactbasic/{src/components.json → components.json} +0 -0
@@ -0,0 +1,225 @@
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
+ /**
18
+ * Manages filter, sort, and cursor-based pagination state for an object search page.
19
+ *
20
+ * ## State model
21
+ * Local React state is the primary driver for instant UI updates.
22
+ * URL search params act as the durable source of truth so that a page
23
+ * refresh or shared link restores the same view. Changes are synced to
24
+ * the URL via a debounced write (300 ms) to avoid excessive history entries.
25
+ *
26
+ * ## Return shape
27
+ * Returns memoized groups so each group's reference is stable unless its
28
+ * contents change — safe to pass directly as props to `React.memo` children.
29
+ *
30
+ * - `filters` — active filter values + set/remove callbacks
31
+ * - `sort` — current sort state + set callback
32
+ * - `query` — derived `where` / `orderBy` objects ready for the API
33
+ * - `pagination` — page size, page index, cursor, and navigation callbacks
34
+ * - `resetAll` — clears all filters, sort, and pagination in one call
35
+ */
36
+ export function useObjectSearchParams<TFilter, TOrderBy>(
37
+ filterConfigs: FilterFieldConfig[],
38
+ _sortConfigs?: SortFieldConfig[],
39
+ paginationConfig?: PaginationConfig,
40
+ ) {
41
+ const defaultPageSize = paginationConfig?.defaultPageSize ?? 10;
42
+ const validPageSizes = paginationConfig?.validPageSizes ?? [defaultPageSize];
43
+ const [searchParams, setSearchParams] = useSearchParams();
44
+
45
+ // Seed local state from URL on initial load
46
+ const initial = useMemo(
47
+ () => searchParamsToFilters(searchParams, filterConfigs),
48
+ // Only run on mount — local state takes over after that, no deps needed
49
+ // eslint-disable-next-line react-hooks/exhaustive-deps
50
+ [],
51
+ );
52
+
53
+ const [filters, setFilters] = useState<ActiveFilterValue[]>(initial.filters);
54
+ const [sort, setLocalSort] = useState<SortState | null>(initial.sort);
55
+
56
+ // Pagination — cursor-based with a stack to support "previous page" navigation.
57
+ const getValidPageSize = (size: number) =>
58
+ validPageSizes.includes(size) ? size : defaultPageSize;
59
+
60
+ const [pageSize, setPageSizeState] = useState<number>(
61
+ getValidPageSize(initial.pageSize ?? defaultPageSize),
62
+ );
63
+ const [pageIndex, setPageIndex] = useState(initial.pageIndex);
64
+ const [afterCursor, setAfterCursor] = useState<string | undefined>(undefined);
65
+ const cursorStackRef = useRef<string[]>([]);
66
+
67
+ // Debounced URL sync — keeps URL in sync without blocking the UI
68
+ const syncToUrl = useCallback(
69
+ (
70
+ nextFilters: ActiveFilterValue[],
71
+ nextSort: SortState | null,
72
+ nextPageSize?: number,
73
+ nextPageIndex?: number,
74
+ ) => {
75
+ const params = filtersToSearchParams(nextFilters, nextSort, nextPageSize, nextPageIndex);
76
+ setSearchParams(params, { replace: true });
77
+ },
78
+ [setSearchParams],
79
+ );
80
+
81
+ const debouncedSyncRef = useRef(debounce(syncToUrl, URL_SYNC_DEBOUNCE_MS));
82
+ useEffect(() => {
83
+ debouncedSyncRef.current = debounce(syncToUrl, URL_SYNC_DEBOUNCE_MS);
84
+ }, [syncToUrl]);
85
+
86
+ // Snapshot ref — lets callbacks read the latest state without being
87
+ // recreated on every render (avoids infinite useCallback chains).
88
+ const stateRef = useRef({ filters, sort, pageSize, pageIndex });
89
+ stateRef.current = { filters, sort, pageSize, pageIndex };
90
+
91
+ // Any filter/sort change resets pagination to the first page.
92
+ const resetPagination = useCallback(() => {
93
+ setPageIndex(0);
94
+ setAfterCursor(undefined);
95
+ cursorStackRef.current = [];
96
+ }, []);
97
+
98
+ // -- Filter callbacks -------------------------------------------------------
99
+
100
+ const setFilter = useCallback(
101
+ (field: string, value: ActiveFilterValue | undefined) => {
102
+ const { sort: s, pageSize: ps } = stateRef.current;
103
+ setFilters((prev) => {
104
+ const next = prev.filter((f) => f.field !== field);
105
+ if (value) next.push(value);
106
+ debouncedSyncRef.current(next, s, ps);
107
+ return next;
108
+ });
109
+ resetPagination();
110
+ },
111
+ [resetPagination],
112
+ );
113
+
114
+ const removeFilter = useCallback(
115
+ (field: string) => {
116
+ const { sort: s, pageSize: ps } = stateRef.current;
117
+ setFilters((prev) => {
118
+ const next = prev.filter((f) => f.field !== field);
119
+ debouncedSyncRef.current(next, s, ps);
120
+ return next;
121
+ });
122
+ resetPagination();
123
+ },
124
+ [resetPagination],
125
+ );
126
+
127
+ // -- Sort callback ----------------------------------------------------------
128
+
129
+ const setSort = useCallback(
130
+ (nextSort: SortState | null) => {
131
+ const { filters: f, pageSize: ps } = stateRef.current;
132
+ setLocalSort(nextSort);
133
+ debouncedSyncRef.current(f, nextSort, ps);
134
+ resetPagination();
135
+ },
136
+ [resetPagination],
137
+ );
138
+
139
+ // -- Reset ------------------------------------------------------------------
140
+
141
+ const resetAll = useCallback(() => {
142
+ setFilters([]);
143
+ setLocalSort(null);
144
+ resetPagination();
145
+ syncToUrl([], null, defaultPageSize, 0);
146
+ setPageSizeState(defaultPageSize);
147
+ }, [syncToUrl, resetPagination]);
148
+
149
+ // -- Pagination callbacks ---------------------------------------------------
150
+ // Uses a cursor stack to track visited pages. "Next" pushes the current
151
+ // endCursor onto the stack; "Previous" pops it to restore the prior cursor.
152
+
153
+ const goToNextPage = useCallback((endCursor: string) => {
154
+ cursorStackRef.current = [...cursorStackRef.current, endCursor];
155
+ setAfterCursor(endCursor);
156
+ setPageIndex((prev) => {
157
+ const nextIndex = prev + 1;
158
+ const { filters: f, sort: s, pageSize: ps } = stateRef.current;
159
+ debouncedSyncRef.current(f, s, ps, nextIndex);
160
+ return nextIndex;
161
+ });
162
+ }, []);
163
+
164
+ const goToPreviousPage = useCallback(() => {
165
+ const stack = cursorStackRef.current;
166
+ const next = stack.slice(0, -1);
167
+ cursorStackRef.current = next;
168
+ setAfterCursor(next.length > 0 ? next[next.length - 1] : undefined);
169
+ setPageIndex((prev) => {
170
+ const nextIndex = Math.max(0, prev - 1);
171
+ const { filters: f, sort: s, pageSize: ps } = stateRef.current;
172
+ debouncedSyncRef.current(f, s, ps, nextIndex);
173
+ return nextIndex;
174
+ });
175
+ }, []);
176
+
177
+ const setPageSize = useCallback(
178
+ (newSize: number) => {
179
+ const validated = getValidPageSize(newSize);
180
+ const { filters: f, sort: s } = stateRef.current;
181
+ setPageSizeState(validated);
182
+ resetPagination();
183
+ debouncedSyncRef.current(f, s, validated);
184
+ },
185
+ [resetPagination],
186
+ );
187
+
188
+ // -- Derived query objects ---------------------------------------------------
189
+ // Translate local filter/sort state into API-ready `where` and `orderBy`.
190
+
191
+ const where = useMemo(
192
+ () => buildFilter<TFilter>(filters, filterConfigs),
193
+ [filters, filterConfigs],
194
+ );
195
+
196
+ const orderBy = useMemo(() => buildOrderBy<TOrderBy>(sort), [sort]);
197
+
198
+ // -- Memoized return groups -------------------------------------------------
199
+ // Each group is individually memoized so its object reference stays stable
200
+ // unless the contained values change. This makes it safe to pass a group
201
+ // (e.g. `pagination`) directly as props to a React.memo child without
202
+ // causing unnecessary re-renders.
203
+
204
+ const filtersGroup = useMemo(
205
+ () => ({ active: filters, set: setFilter, remove: removeFilter }),
206
+ [filters, setFilter, removeFilter],
207
+ );
208
+
209
+ const sortGroup = useMemo(() => ({ current: sort, set: setSort }), [sort, setSort]);
210
+
211
+ const query = useMemo(() => ({ where, orderBy }), [where, orderBy]);
212
+
213
+ const pagination = useMemo(
214
+ () => ({ pageSize, pageIndex, afterCursor, setPageSize, goToNextPage, goToPreviousPage }),
215
+ [pageSize, pageIndex, afterCursor, setPageSize, goToNextPage, goToPreviousPage],
216
+ );
217
+
218
+ return {
219
+ filters: filtersGroup,
220
+ sort: sortGroup,
221
+ query,
222
+ pagination,
223
+ resetAll,
224
+ };
225
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Creates a debounced version of the provided function.
3
+ *
4
+ * Each call to the returned function resets the internal timer. The wrapped
5
+ * function is only invoked once the timer expires without being reset. This
6
+ * makes it ideal for rate-limiting high-frequency events like input changes.
7
+ *
8
+ * @typeParam T - The function signature to debounce.
9
+ * @param fn - The function to debounce.
10
+ * @param ms - The debounce delay in milliseconds.
11
+ * @returns A new function with the same signature that delays execution.
12
+ */
13
+ export function debounce<T extends (...args: never[]) => void>(
14
+ fn: T,
15
+ ms: number,
16
+ ): (...args: Parameters<T>) => void {
17
+ let timer: ReturnType<typeof setTimeout> | undefined;
18
+ return (...args: Parameters<T>) => {
19
+ clearTimeout(timer);
20
+ timer = setTimeout(() => fn(...args), ms);
21
+ };
22
+ }
@@ -0,0 +1,29 @@
1
+ export function fieldValue(
2
+ field: { displayValue?: string | null; value?: unknown } | null | undefined,
3
+ ): string | null {
4
+ if (field?.displayValue != null) return field.displayValue;
5
+ if (field?.value != null) return String(field.value);
6
+ return null;
7
+ }
8
+
9
+ export function getAddressFieldLines(address: {
10
+ street?: string | null;
11
+ city?: string | null;
12
+ state?: string | null;
13
+ postalCode?: string | null;
14
+ country?: string | null;
15
+ }) {
16
+ const cityStateZip = [address.city, address.state].filter(Boolean).join(", ");
17
+ const cityStateZipLine = [cityStateZip, address.postalCode].filter(Boolean).join(" ");
18
+ const lines = [address.street, cityStateZipLine, address.country].filter(Boolean);
19
+ if (lines.length === 0) return null;
20
+ return lines;
21
+ }
22
+
23
+ export function formatDateTimeField(
24
+ value?: string | null,
25
+ ...args: Parameters<Date["toLocaleString"]>
26
+ ) {
27
+ if (!value) return null;
28
+ return new Date(value).toLocaleString(...args);
29
+ }
@@ -0,0 +1,372 @@
1
+ /**
2
+ * filterUtils.ts
3
+ *
4
+ * Centralizes all filter-related transformations for the object search feature.
5
+ * This module handles two distinct concerns:
6
+ *
7
+ * 1. **URL serialization** — Converting filter/sort state to and from
8
+ * URLSearchParams so that search criteria can be bookmarked, shared, and
9
+ * restored on page load.
10
+ *
11
+ * 2. **GraphQL query building** — Converting the same filter state into the
12
+ * `where` clause shape expected by the GraphQL API.
13
+ *
14
+ * Both concerns operate on the shared {@link ActiveFilterValue} type, which
15
+ * represents a single active filter with a field name, filter type, and one or
16
+ * more values (value, min, max).
17
+ */
18
+
19
+ import type { SortState } from "./sortUtils";
20
+
21
+ export type FilterFieldType =
22
+ | "text"
23
+ | "picklist"
24
+ | "numeric"
25
+ | "boolean"
26
+ | "date"
27
+ | "daterange"
28
+ | "multipicklist"
29
+ | "search";
30
+
31
+ export type FilterFieldConfig<TFieldName extends string = string> = {
32
+ field: TFieldName;
33
+ label: string;
34
+ type: FilterFieldType;
35
+ placeholder?: string;
36
+ /** Required for picklist type. */
37
+ options?: Array<{ value: string; label: string }>;
38
+ helpText?: string;
39
+ /** Required for search type — the fields to match against with `or`. */
40
+ searchFields?: string[];
41
+ };
42
+
43
+ export type ActiveFilterValue<TFieldName extends string = string> = {
44
+ field: TFieldName;
45
+ label: string;
46
+ type: FilterFieldType;
47
+ value?: string;
48
+ min?: string;
49
+ max?: string;
50
+ };
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // URL Serialization
54
+ // ---------------------------------------------------------------------------
55
+
56
+ /**
57
+ * Prefix applied to all filter-related URL search params.
58
+ * This namespaces filter params so they don't collide with other query params
59
+ * (e.g. pagination, feature flags).
60
+ *
61
+ * @example "f.Industry=Technology" or "f.AnnualRevenue.min=1000000"
62
+ */
63
+ const FILTER_PREFIX = "f.";
64
+
65
+ /** URL param key for the multi-field search term. */
66
+ const SEARCH_KEY = "q";
67
+
68
+ /** URL param key for the currently sorted field name. */
69
+ const SORT_KEY = "sort";
70
+
71
+ /** URL param key for the sort direction (ASC or DESC). */
72
+ const DIR_KEY = "dir";
73
+
74
+ /** URL param key for the page size preference. */
75
+ const PAGE_SIZE_KEY = "ps";
76
+ const PAGE_KEY = "page";
77
+
78
+ /**
79
+ * Serializes filter and sort state into URLSearchParams.
80
+ *
81
+ * Encoding scheme:
82
+ * - Simple values (text, picklist, boolean, multipicklist):
83
+ * `f.<field>=<value>`
84
+ * - Range values (numeric, date, daterange):
85
+ * `f.<field>.min=<min>` and/or `f.<field>.max=<max>`
86
+ * - Sort: `sort=<field>&dir=ASC|DESC`
87
+ *
88
+ * @param filters - The currently active filters to serialize.
89
+ * @param sort - The current sort state, or null if no sort is applied.
90
+ * @returns A URLSearchParams instance representing the full search state.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * const params = filtersToSearchParams(
95
+ * [{ field: "Industry", type: "picklist", value: "Technology" }],
96
+ * { field: "Name", direction: "ASC" },
97
+ * );
98
+ * // params.toString() => "f.Industry=Technology&sort=Name&dir=ASC"
99
+ * ```
100
+ */
101
+ export function filtersToSearchParams(
102
+ filters: ActiveFilterValue[],
103
+ sort: SortState | null,
104
+ pageSize?: number,
105
+ pageIndex?: number,
106
+ ): URLSearchParams {
107
+ const params = new URLSearchParams();
108
+
109
+ for (const filter of filters) {
110
+ if (filter.type === "search") {
111
+ if (filter.value) params.set(SEARCH_KEY, filter.value);
112
+ continue;
113
+ }
114
+ if (filter.value !== undefined && filter.value !== "") {
115
+ params.set(`${FILTER_PREFIX}${filter.field}`, filter.value);
116
+ }
117
+ if (filter.min !== undefined && filter.min !== "") {
118
+ params.set(`${FILTER_PREFIX}${filter.field}.min`, filter.min);
119
+ }
120
+ if (filter.max !== undefined && filter.max !== "") {
121
+ params.set(`${FILTER_PREFIX}${filter.field}.max`, filter.max);
122
+ }
123
+ }
124
+
125
+ if (sort) {
126
+ params.set(SORT_KEY, sort.field);
127
+ params.set(DIR_KEY, sort.direction);
128
+ }
129
+
130
+ if (pageSize !== undefined) {
131
+ params.set(PAGE_SIZE_KEY, String(pageSize));
132
+ }
133
+
134
+ if (pageIndex !== undefined && pageIndex > 0) {
135
+ params.set(PAGE_KEY, String(pageIndex + 1));
136
+ }
137
+
138
+ return params;
139
+ }
140
+
141
+ /**
142
+ * Deserializes URLSearchParams back into filter and sort state.
143
+ *
144
+ * Requires the full list of filter configs so it knows which URL params to look
145
+ * for and what type each filter is. Params that don't match a known config are
146
+ * silently ignored, making this safe against stale or hand-edited URLs.
147
+ *
148
+ * @param params - The URLSearchParams to parse (typically from the browser URL).
149
+ * @param configs - The filter field configurations defining available filters.
150
+ * @returns An object containing the deserialized `filters` array and `sort` state.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * const url = new URLSearchParams("f.Industry=Technology&sort=Name&dir=ASC");
155
+ * const { filters, sort } = searchParamsToFilters(url, filterConfigs);
156
+ * // filters => [{ field: "Industry", type: "picklist", value: "Technology" }]
157
+ * // sort => { field: "Name", direction: "ASC" }
158
+ * ```
159
+ */
160
+ export function searchParamsToFilters(
161
+ params: URLSearchParams,
162
+ configs: FilterFieldConfig[],
163
+ ): {
164
+ filters: ActiveFilterValue[];
165
+ sort: SortState | null;
166
+ pageSize: number | undefined;
167
+ pageIndex: number;
168
+ } {
169
+ const filters: ActiveFilterValue[] = [];
170
+
171
+ for (const config of configs) {
172
+ const { field, label, type } = config;
173
+
174
+ if (type === "search") {
175
+ const q = params.get(SEARCH_KEY);
176
+ if (q) {
177
+ filters.push({ field, label, type: "search", value: q });
178
+ }
179
+ continue;
180
+ }
181
+
182
+ const value = params.get(`${FILTER_PREFIX}${field}`) ?? undefined;
183
+ const min = params.get(`${FILTER_PREFIX}${field}.min`) ?? undefined;
184
+ const max = params.get(`${FILTER_PREFIX}${field}.max`) ?? undefined;
185
+
186
+ const hasValue = value !== undefined && value !== "";
187
+ const hasRange = (min !== undefined && min !== "") || (max !== undefined && max !== "");
188
+
189
+ if (hasValue || hasRange) {
190
+ filters.push({ field, label, type, value, min, max });
191
+ }
192
+ }
193
+
194
+ let sort: SortState | null = null;
195
+ const sortField = params.get(SORT_KEY);
196
+ const sortDir = params.get(DIR_KEY);
197
+ if (sortField) {
198
+ sort = {
199
+ field: sortField,
200
+ direction: sortDir === "DESC" ? "DESC" : "ASC",
201
+ };
202
+ }
203
+
204
+ const pageSizeRaw = params.get(PAGE_SIZE_KEY);
205
+ const pageSize = pageSizeRaw ? parseInt(pageSizeRaw, 10) : undefined;
206
+
207
+ const pageRaw = params.get(PAGE_KEY);
208
+ const page = pageRaw ? parseInt(pageRaw, 10) : 1;
209
+ const pageIndex = !isNaN(page) && page > 1 ? page - 1 : 0;
210
+
211
+ return {
212
+ filters,
213
+ sort,
214
+ pageSize: pageSize && !isNaN(pageSize) ? pageSize : undefined,
215
+ pageIndex,
216
+ };
217
+ }
218
+
219
+ // ---------------------------------------------------------------------------
220
+ // GraphQL Filter Building
221
+ // ---------------------------------------------------------------------------
222
+
223
+ /**
224
+ * Converts an array of active filter values into a GraphQL `where` clause.
225
+ *
226
+ * Each filter is individually converted to a clause via {@link buildSingleFilter},
227
+ * then multiple clauses are combined with a top-level `and` operator. This ensures
228
+ * all active filters are applied simultaneously (intersection semantics).
229
+ *
230
+ * @typeParam TFilter - The GraphQL filter input type (e.g. `AccountFilterInput`).
231
+ * @param filters - The active filters to convert.
232
+ * @returns A filter object for the GraphQL `where` variable, or `undefined` if
233
+ * no filters are active (which tells the API to return unfiltered results).
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * const where = buildFilter<AccountFilterInput>([
238
+ * { field: "Industry", type: "picklist", value: "Technology" },
239
+ * { field: "AnnualRevenue", type: "numeric", min: "1000000" },
240
+ * ]);
241
+ * // where => { and: [
242
+ * // { Industry: { eq: "Technology" } },
243
+ * // { AnnualRevenue: { gte: 1000000 } },
244
+ * // ]}
245
+ * ```
246
+ */
247
+ export function buildFilter<TFilter>(
248
+ filters: ActiveFilterValue[],
249
+ configs: FilterFieldConfig[],
250
+ ): TFilter | undefined {
251
+ const configMap = new Map(configs.map((c) => [c.field, c]));
252
+ const clauses: TFilter[] = [];
253
+
254
+ for (const filter of filters) {
255
+ const clause = buildSingleFilter<TFilter>(filter, configMap.get(filter.field));
256
+ if (clause) clauses.push(clause);
257
+ }
258
+
259
+ if (clauses.length === 0) return undefined;
260
+ if (clauses.length === 1) return clauses[0];
261
+ return { and: clauses } as TFilter;
262
+ }
263
+
264
+ /**
265
+ * Converts a YYYY-MM-DD date string to a full ISO-8601 datetime at midnight UTC.
266
+ * Used as the inclusive lower bound for date range queries.
267
+ */
268
+ function toStartOfDay(dateStr: string): string {
269
+ return `${dateStr}T00:00:00.000Z`;
270
+ }
271
+
272
+ /**
273
+ * Converts a YYYY-MM-DD date string to a full ISO-8601 datetime at the last
274
+ * millisecond of the day in UTC. Used as the inclusive upper bound for date
275
+ * range queries.
276
+ */
277
+ function toEndOfDay(dateStr: string): string {
278
+ return `${dateStr}T23:59:59.999Z`;
279
+ }
280
+
281
+ /**
282
+ * Converts a single active filter value into a GraphQL filter clause.
283
+ *
284
+ * Supported filter types and their GraphQL mappings:
285
+ *
286
+ * | Type | GraphQL operator(s) | Example output |
287
+ * |-----------------|---------------------|----------------------------------------------------------|
288
+ * | `text` | `like` | `{ Name: { like: "%Acme%" } }` |
289
+ * | `picklist` | `eq` | `{ Industry: { eq: "Technology" } }` |
290
+ * | `multipicklist` | `eq` or `in` | `{ Type: { in: ["A", "B"] } }` |
291
+ * | `numeric` | `gte` / `lte` | `{ Revenue: { gte: 1000, lte: 5000 } }` |
292
+ * | `boolean` | `eq` | `{ IsActive: { eq: true } }` |
293
+ * | `date` | dynamic operator | `{ CreatedDate: { gte: { value: "..." } } }` |
294
+ * | `daterange` | `gte` + `lte` | Combined with `and` if both bounds set |
295
+ * | `search` | `like` + `or` | `{ or: [{ Name: { like: "%x%" } }, { Phone: { like: "%x%" } }] }` |
296
+ *
297
+ * The `search` type uses `config.searchFields` to build an `or` clause that
298
+ * matches the search term across multiple fields simultaneously (union semantics).
299
+ *
300
+ * @param filter - The active filter value to convert.
301
+ * @param config - The corresponding field config. Required for `search` type
302
+ * (provides `searchFields`); optional for all other types.
303
+ * @returns A single filter clause, or `null` if the filter has no meaningful value.
304
+ */
305
+ function buildSingleFilter<TFilter>(
306
+ filter: ActiveFilterValue,
307
+ config?: FilterFieldConfig,
308
+ ): TFilter | null {
309
+ const { field, type, value, min, max } = filter;
310
+
311
+ switch (type) {
312
+ case "text": {
313
+ if (!value) return null;
314
+ return { [field]: { like: `%${value}%` } } as TFilter;
315
+ }
316
+ case "picklist": {
317
+ if (!value) return null;
318
+ return { [field]: { eq: value } } as TFilter;
319
+ }
320
+ case "numeric": {
321
+ if (!min && !max) return null;
322
+ const ops: Record<string, number> = {};
323
+ if (min) ops.gte = Number(min);
324
+ if (max) ops.lte = Number(max);
325
+ return { [field]: ops } as TFilter;
326
+ }
327
+ case "boolean": {
328
+ if (value === undefined || value === "") return null;
329
+ return { [field]: { eq: value === "true" } } as TFilter;
330
+ }
331
+ case "multipicklist": {
332
+ if (!value) return null;
333
+ const values = value.split(",");
334
+ if (values.length === 1) {
335
+ return { [field]: { eq: values[0] } } as TFilter;
336
+ }
337
+ return { [field]: { in: values } } as TFilter;
338
+ }
339
+ case "date": {
340
+ if (!min && !max) return null;
341
+ const op = value ?? (min ? "gte" : "lte");
342
+ const dateStr = min ?? max;
343
+ const isoStr = op === "gte" || op === "gt" ? toStartOfDay(dateStr!) : toEndOfDay(dateStr!);
344
+ return { [field]: { [op]: { value: isoStr } } } as TFilter;
345
+ }
346
+ case "daterange": {
347
+ if (!min && !max) return null;
348
+ const clauses: TFilter[] = [];
349
+ if (min) {
350
+ clauses.push({
351
+ [field]: { gte: { value: toStartOfDay(min) } },
352
+ } as TFilter);
353
+ }
354
+ if (max) {
355
+ clauses.push({
356
+ [field]: { lte: { value: toEndOfDay(max) } },
357
+ } as TFilter);
358
+ }
359
+ return clauses.length === 1 ? clauses[0] : ({ and: clauses } as TFilter);
360
+ }
361
+ case "search": {
362
+ if (!value) return null;
363
+ const searchFields = config?.searchFields ?? [];
364
+ if (searchFields.length === 0) return null;
365
+ const clauses = searchFields.map((f) => ({ [f]: { like: `%${value}%` } }) as TFilter);
366
+ if (clauses.length === 1) return clauses[0];
367
+ return { or: clauses } as TFilter;
368
+ }
369
+ default:
370
+ return null;
371
+ }
372
+ }
@@ -0,0 +1,38 @@
1
+ import { ResultOrder, NullOrder } from "../../../api/graphql-operations-types";
2
+
3
+ export type SortFieldConfig<TFieldName extends string = string> = {
4
+ field: TFieldName;
5
+ label: string;
6
+ };
7
+
8
+ export type SortState<TFieldName extends string = string> = {
9
+ field: TFieldName;
10
+ direction: "ASC" | "DESC";
11
+ };
12
+
13
+ /**
14
+ * Converts a {@link SortState} into a GraphQL order-by object.
15
+ *
16
+ * @typeParam TOrderBy - The GraphQL order-by input type (e.g. `AccountOrderByInput`).
17
+ * @param sort - The current sort state from the UI, or `null` if no sort is applied.
18
+ * @returns An order-by object for the GraphQL query's `orderBy` variable, or
19
+ * `undefined` if no sort is active (which uses the API's default ordering).
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const orderBy = buildOrderBy<AccountOrderByInput>({
24
+ * field: "Name",
25
+ * direction: "ASC",
26
+ * });
27
+ * // orderBy => { Name: { order: ResultOrder.Asc, nulls: NullOrder.Last } }
28
+ * ```
29
+ */
30
+ export function buildOrderBy<TOrderBy>(sort: SortState | null): TOrderBy | undefined {
31
+ if (!sort) return undefined;
32
+ return {
33
+ [sort.field]: {
34
+ order: sort.direction === "ASC" ? ResultOrder.Asc : ResultOrder.Desc,
35
+ nulls: NullOrder.Last,
36
+ },
37
+ } as TOrderBy;
38
+ }