@salesforce/templates 66.13.4 → 66.13.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 (236) hide show
  1. package/lib/generators/baseGenerator.d.ts +2 -0
  2. package/lib/generators/baseGenerator.js +353 -0
  3. package/lib/generators/baseGenerator.js.map +1 -1
  4. package/lib/index.d.ts +1 -0
  5. package/lib/index.js +3 -1
  6. package/lib/index.js.map +1 -1
  7. package/lib/templates/project/angularextapp/CHANGELOG.md +258 -0
  8. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +1 -1
  9. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
  10. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
  11. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +421 -394
  12. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +2 -2
  13. package/lib/templates/project/angularextapp/package.json +1 -1
  14. package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +17 -0
  15. package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +33 -3
  16. package/lib/templates/project/angularextapp/scripts/org-setup.mjs +535 -3
  17. package/lib/templates/project/angularintapp/CHANGELOG.md +266 -0
  18. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +1 -1
  19. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
  20. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
  21. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +431 -404
  22. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +2 -2
  23. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +6 -1
  24. package/lib/templates/project/angularintapp/package.json +1 -1
  25. package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +17 -0
  26. package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +33 -3
  27. package/lib/templates/project/angularintapp/scripts/org-setup.mjs +535 -3
  28. package/lib/templates/project/reactexternalapp/CHANGELOG.md +1313 -0
  29. package/lib/templates/project/reactexternalapp/PRD.md +38 -0
  30. package/lib/templates/project/reactexternalapp/README.md +14 -10
  31. package/lib/templates/project/reactexternalapp/_p_/_m_/_ps_/reactexternalapp_Guest_User_Api_Access.permissionset-meta.xml +25 -0
  32. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +660 -692
  33. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +9 -7
  34. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +8 -5
  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/api/distinctValuesService.ts +84 -0
  38. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +71 -0
  39. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +277 -0
  40. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +185 -0
  41. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +77 -0
  42. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +182 -0
  43. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
  44. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +55 -0
  45. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
  46. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
  47. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
  48. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
  49. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
  50. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  51. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
  52. 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
  53. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
  54. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
  55. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
  56. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
  57. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
  58. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +83 -0
  59. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
  60. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
  61. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +703 -0
  62. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +90 -0
  63. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  64. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +156 -0
  65. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +307 -0
  66. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  67. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  68. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
  69. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  70. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphqlClient.ts +24 -8
  71. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/appLayout.tsx +7 -0
  72. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/CustomerWebClientChat.tsx +74 -0
  73. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
  74. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  75. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
  76. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
  77. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/index.ts +6 -0
  78. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +49 -16
  79. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +21 -293
  80. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +22 -7
  81. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/TestChatPage.tsx +26 -0
  82. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +11 -5
  83. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/types/chat.ts +36 -0
  84. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
  85. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
  86. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  87. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls +133 -0
  88. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls-meta.xml +5 -0
  89. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls +101 -0
  90. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls-meta.xml +5 -0
  91. package/lib/templates/project/reactexternalapp/_p_/_m_/package.xml +4 -0
  92. package/lib/templates/project/reactexternalapp/package.json +8 -2
  93. package/lib/templates/project/reactexternalapp/scripts/org-setup-config-schema.mjs +120 -0
  94. package/lib/templates/project/reactexternalapp/scripts/org-setup-dev.mjs +87 -0
  95. package/lib/templates/project/reactexternalapp/scripts/org-setup-utils.mjs +569 -0
  96. package/lib/templates/project/reactexternalapp/scripts/org-setup-xml.mjs +182 -0
  97. package/lib/templates/project/reactexternalapp/scripts/org-setup.config.json +6 -2
  98. package/lib/templates/project/reactexternalapp/scripts/org-setup.mjs +1509 -328
  99. package/lib/templates/project/reactexternalapp/scripts/validate-org-setup-config.mjs +38 -0
  100. package/lib/templates/project/reactinternalapp/CHANGELOG.md +1127 -0
  101. package/lib/templates/project/reactinternalapp/PRD.md +35 -0
  102. package/lib/templates/project/reactinternalapp/README.md +14 -10
  103. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +509 -505
  104. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package.json +9 -8
  105. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
  106. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +71 -0
  107. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +277 -0
  108. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +185 -0
  109. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +77 -0
  110. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +182 -0
  111. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
  112. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +55 -0
  113. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
  114. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
  115. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
  116. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
  117. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
  118. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  119. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
  120. 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
  121. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
  122. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
  123. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
  124. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
  125. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
  126. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +83 -0
  127. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
  128. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
  129. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +703 -0
  130. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +90 -0
  131. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  132. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +156 -0
  133. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +307 -0
  134. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  135. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  136. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
  137. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  138. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.tsx +16 -132
  139. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
  140. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  141. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
  142. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
  143. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +49 -16
  144. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +21 -293
  145. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +21 -6
  146. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +4 -4
  147. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
  148. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
  149. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  150. package/lib/templates/project/reactinternalapp/package.json +4 -2
  151. package/lib/templates/project/reactinternalapp/scripts/org-setup-config-schema.mjs +24 -0
  152. package/lib/templates/project/reactinternalapp/scripts/org-setup-dev.mjs +87 -0
  153. package/lib/templates/project/reactinternalapp/scripts/org-setup-utils.mjs +569 -0
  154. package/lib/templates/project/reactinternalapp/scripts/org-setup-xml.mjs +182 -0
  155. package/lib/templates/project/reactinternalapp/scripts/org-setup.mjs +1162 -214
  156. package/lib/templates/uiBundles/angularbasic/angular.json +1 -1
  157. package/lib/templates/uiBundles/angularbasic/eslint-plugin-angular-graphql.js +148 -0
  158. package/lib/templates/uiBundles/angularbasic/eslint.config.js +9 -1
  159. package/lib/templates/uiBundles/angularbasic/package-lock.json +421 -394
  160. package/lib/templates/uiBundles/angularbasic/package.json +2 -2
  161. package/lib/templates/uiBundles/reactbasic/package-lock.json +445 -418
  162. package/lib/utils/template-placeholders.js +7 -0
  163. package/lib/utils/template-placeholders.js.map +1 -1
  164. package/lib/utils/uiBundleTemplateUtils.d.ts +3 -1
  165. package/lib/utils/uiBundleTemplateUtils.js +4 -1
  166. package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
  167. package/package.json +7 -7
  168. package/lib/templates/project/reactexternalapp/AGENT.md +0 -252
  169. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
  170. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
  171. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
  172. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
  173. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
  174. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
  175. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
  176. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
  177. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
  178. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
  179. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
  180. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
  181. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
  182. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
  183. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
  184. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
  185. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
  186. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
  187. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
  188. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
  189. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
  190. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
  191. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
  192. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
  193. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
  194. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
  195. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
  196. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
  197. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
  198. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
  199. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
  200. package/lib/templates/project/reactexternalapp/scripts/prepare-import-unique-fields.js +0 -122
  201. package/lib/templates/project/reactinternalapp/AGENT.md +0 -252
  202. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
  203. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
  204. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
  205. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
  206. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
  207. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
  208. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
  209. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
  210. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
  211. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
  212. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
  213. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
  214. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
  215. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
  216. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
  217. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
  218. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
  219. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
  220. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
  221. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
  222. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
  223. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
  224. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
  225. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
  226. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
  227. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
  228. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
  229. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
  230. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
  231. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
  232. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
  233. package/lib/templates/project/reactinternalapp/scripts/prepare-import-unique-fields.js +0 -122
  234. /package/lib/templates/project/angularextapp/_p_/_m_/{permissionsets → _ps_}/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +0 -0
  235. /package/lib/templates/project/angularintapp/_p_/_m_/{permissionsets → _ps_}/angularintapp_Access.permissionset-meta.xml +0 -0
  236. /package/lib/templates/project/reactinternalapp/_p_/_m_/{permissionsets → _ps_}/reactinternalapp_Access.permissionset-meta.xml +0 -0
@@ -1,355 +0,0 @@
1
- import { useState } from "react";
2
- import { useParams, useNavigate } from "react-router";
3
- import { createDataSDK } from "@salesforce/platform-sdk";
4
- import { AlertCircle, ChevronDown, ChevronRight, FileQuestion } from "lucide-react";
5
- import GET_ACCOUNT_DETAIL from "../api/query/getAccountDetail.graphql?raw";
6
- import type {
7
- GetAccountDetailQuery,
8
- GetAccountDetailQueryVariables,
9
- } from "../../../../api/graphql-operations-types";
10
- import { Alert, AlertTitle, AlertDescription } from "../../../../components/ui/alert";
11
- import { Button } from "../../../../components/ui/button";
12
- import { Card, CardContent } from "../../../../components/ui/card";
13
- import { fieldValue, getAddressFieldLines, formatDateTimeField } from "../../utils/fieldUtils";
14
- import {
15
- Collapsible,
16
- CollapsibleTrigger,
17
- CollapsibleContent,
18
- } from "../../../../components/ui/collapsible";
19
- import { Separator } from "../../../../components/ui/separator";
20
- import { Skeleton } from "../../../../components/ui/skeleton";
21
- import { useAsyncData } from "../../hooks/useAsyncData";
22
- import { ObjectBreadcrumb } from "../../components/ObjectBreadcrumb";
23
-
24
- type AccountNode = NonNullable<
25
- NonNullable<
26
- NonNullable<NonNullable<GetAccountDetailQuery["uiapi"]["query"]["Account"]>["edges"]>[number]
27
- >["node"]
28
- >;
29
-
30
- async function fetchAccountDetail(recordId: string): Promise<AccountNode | null | undefined> {
31
- const data = await createDataSDK();
32
- const result = await data.graphql!.query<GetAccountDetailQuery, GetAccountDetailQueryVariables>({
33
- query: GET_ACCOUNT_DETAIL,
34
- variables: { id: recordId },
35
- });
36
-
37
- if (result.errors?.length) {
38
- throw new Error(result.errors.map((e) => e.message).join("; "));
39
- }
40
-
41
- return result.data?.uiapi?.query?.Account?.edges?.[0]?.node;
42
- }
43
-
44
- export default function AccountObjectDetail() {
45
- const { recordId } = useParams();
46
- const navigate = useNavigate();
47
-
48
- const {
49
- data: account,
50
- loading,
51
- error,
52
- } = useAsyncData(() => fetchAccountDetail(recordId!), [recordId]);
53
-
54
- return (
55
- <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
56
- <ObjectBreadcrumb
57
- listPath="/accounts"
58
- listLabel="Accounts"
59
- loading={loading}
60
- recordName={
61
- account
62
- ? (fieldValue(account.Name) ?? "")
63
- : error
64
- ? "Error"
65
- : loading
66
- ? undefined
67
- : "Not Found"
68
- }
69
- />
70
-
71
- {/* Loading state */}
72
- {loading && <AccountDetailSkeleton />}
73
-
74
- {/* Error state */}
75
- {error && <AccountDetailError onBack={() => navigate(-1)} />}
76
-
77
- {/* Not found state */}
78
- {!loading && !error && !account && <AccountDetailNotFound onBack={() => navigate(-1)} />}
79
-
80
- {/* Content */}
81
- {account && <AccountDetailContent account={account} />}
82
- </div>
83
- );
84
- }
85
-
86
- function AccountDetailContent({ account }: { account: AccountNode }) {
87
- const billingAddress = getAddressFieldLines({
88
- street: fieldValue(account.BillingStreet),
89
- city: fieldValue(account.BillingCity),
90
- state: fieldValue(account.BillingState),
91
- postalCode: fieldValue(account.BillingPostalCode),
92
- country: fieldValue(account.BillingCountry),
93
- });
94
-
95
- const shippingAddress = getAddressFieldLines({
96
- street: fieldValue(account.ShippingStreet),
97
- city: fieldValue(account.ShippingCity),
98
- state: fieldValue(account.ShippingState),
99
- postalCode: fieldValue(account.ShippingPostalCode),
100
- country: fieldValue(account.ShippingCountry),
101
- });
102
-
103
- const dateTimeOptions = { dateStyle: "medium", timeStyle: "short" } as const;
104
- const createdDate = formatDateTimeField(
105
- fieldValue(account.CreatedDate),
106
- undefined,
107
- dateTimeOptions,
108
- );
109
- const lastModifiedDate = formatDateTimeField(
110
- fieldValue(account.LastModifiedDate),
111
- undefined,
112
- dateTimeOptions,
113
- );
114
-
115
- return (
116
- <>
117
- <h1 className="text-2xl font-bold mb-4">Account: {fieldValue(account.Name)}</h1>
118
-
119
- <Card>
120
- <CardContent className="space-y-8 pt-6">
121
- {/* Top section */}
122
- <div>
123
- <div className="space-y-4">
124
- <FieldRow>
125
- <FieldItem label="Account Owner">{fieldValue(account.Owner?.Name)}</FieldItem>
126
- <FieldItem label="Phone">
127
- <TelephoneField value={fieldValue(account.Phone)} />
128
- </FieldItem>
129
- </FieldRow>
130
- <FieldRow>
131
- <FieldItem label="Account Name">{fieldValue(account.Name)}</FieldItem>
132
- <FieldItem label="Fax">
133
- <TelephoneField value={fieldValue(account.Fax)} />
134
- </FieldItem>
135
- </FieldRow>
136
- <FieldRow>
137
- <FieldItem label="Parent Account">{fieldValue(account.Parent?.Name)}</FieldItem>
138
- <FieldItem label="Website">{fieldValue(account.Website)}</FieldItem>
139
- </FieldRow>
140
- </div>
141
- </div>
142
-
143
- <Separator />
144
-
145
- {/* Additional Information */}
146
- <Section title="Additional Information">
147
- <FieldRow>
148
- <FieldItem label="Type">{fieldValue(account.Type)}</FieldItem>
149
- <FieldItem label="Employees">{fieldValue(account.NumberOfEmployees)}</FieldItem>
150
- </FieldRow>
151
- <FieldRow>
152
- <FieldItem label="Industry">{fieldValue(account.Industry)}</FieldItem>
153
- <FieldItem label="Annual Revenue">{fieldValue(account.AnnualRevenue)}</FieldItem>
154
- </FieldRow>
155
- <FieldItem label="Description">{fieldValue(account.Description)}</FieldItem>
156
- </Section>
157
-
158
- <Separator />
159
-
160
- {/* Address Information */}
161
- <Section title="Address Information">
162
- <FieldRow>
163
- <FieldItem label="Billing Address">
164
- {billingAddress ? billingAddress.map((line, i) => <div key={i}>{line}</div>) : null}
165
- </FieldItem>
166
- <FieldItem label="Shipping Address">
167
- {shippingAddress
168
- ? shippingAddress.map((line, i) => <div key={i}>{line}</div>)
169
- : null}
170
- </FieldItem>
171
- </FieldRow>
172
- </Section>
173
-
174
- <Separator />
175
-
176
- {/* System Information */}
177
- <Section title="System Information">
178
- <FieldRow>
179
- <FieldItem label="Created By">
180
- {[fieldValue(account.CreatedBy?.Name), createdDate].filter(Boolean).join(" ") ||
181
- null}
182
- </FieldItem>
183
- <FieldItem label="Last Modified By">
184
- {[fieldValue(account.LastModifiedBy?.Name), lastModifiedDate]
185
- .filter(Boolean)
186
- .join(" ") || null}
187
- </FieldItem>
188
- </FieldRow>
189
- </Section>
190
- </CardContent>
191
- </Card>
192
- </>
193
- );
194
- }
195
-
196
- function TelephoneField({ value }: { value?: string | null }) {
197
- if (!value) return null;
198
- return (
199
- <a href={`tel:${value}`} className="underline">
200
- {value}
201
- </a>
202
- );
203
- }
204
-
205
- function FieldItem({ label, children }: { label: string; children: React.ReactNode }) {
206
- return (
207
- <div>
208
- <dt className="text-sm text-muted-foreground">{label}</dt>
209
- <dd className="mt-0.5">{children ?? "—"}</dd>
210
- </div>
211
- );
212
- }
213
-
214
- function FieldRow({ children }: { children: React.ReactNode }) {
215
- return <div className="grid grid-cols-2 gap-x-8 gap-y-4">{children}</div>;
216
- }
217
-
218
- function Section({ title, children }: { title: string; children: React.ReactNode }) {
219
- const [open, setOpen] = useState(true);
220
- return (
221
- <Collapsible open={open} onOpenChange={setOpen}>
222
- <CollapsibleTrigger className="flex items-center gap-2 cursor-pointer text-lg font-semibold py-2">
223
- {open ? <ChevronDown className="size-5" /> : <ChevronRight className="size-5" />}
224
- {title}
225
- </CollapsibleTrigger>
226
- <CollapsibleContent>
227
- <div className="mt-2 space-y-4">{children}</div>
228
- </CollapsibleContent>
229
- </Collapsible>
230
- );
231
- }
232
-
233
- function AccountDetailError({ onBack }: { onBack: () => void }) {
234
- return (
235
- <>
236
- <Alert variant="destructive" role="alert">
237
- <AlertCircle />
238
- <AlertTitle>
239
- <h2>Failed to load account</h2>
240
- </AlertTitle>
241
- <AlertDescription>
242
- Something went wrong while loading this account. Please try again later.
243
- </AlertDescription>
244
- </Alert>
245
- <div className="mt-4 flex gap-3">
246
- <Button variant="outline" onClick={onBack}>
247
- ← Back
248
- </Button>
249
- <Button variant="outline" onClick={() => window.location.reload()}>
250
- Retry
251
- </Button>
252
- </div>
253
- </>
254
- );
255
- }
256
-
257
- function AccountDetailNotFound({ onBack }: { onBack: () => void }) {
258
- return (
259
- <Card>
260
- <CardContent className="flex flex-col items-center justify-center py-16 text-center">
261
- <FileQuestion className="size-12 text-muted-foreground mb-4" />
262
- <h2 className="text-lg font-semibold mb-1">Account not found</h2>
263
- <p className="text-sm text-muted-foreground mb-6">
264
- The account you're looking for doesn't exist or may have been deleted.
265
- </p>
266
- <Button variant="outline" onClick={onBack}>
267
- ← Go back
268
- </Button>
269
- </CardContent>
270
- </Card>
271
- );
272
- }
273
-
274
- function AccountDetailSkeleton() {
275
- return (
276
- <>
277
- <Skeleton className="h-8 w-56 mb-4" />
278
-
279
- <Card>
280
- <CardContent className="space-y-8 pt-6">
281
- {/* Top section: field rows */}
282
- <div>
283
- <div className="space-y-4">
284
- <SkeletonFieldRow />
285
- <SkeletonFieldRow />
286
- <SkeletonFieldRow />
287
- </div>
288
- </div>
289
-
290
- <Separator />
291
-
292
- {/* Additional Information */}
293
- <SkeletonSection />
294
-
295
- <Separator />
296
-
297
- {/* Address Information */}
298
- <div className="space-y-4">
299
- <Skeleton className="h-7 w-48 py-2" />
300
- <div className="grid grid-cols-2 gap-x-8 gap-y-4">
301
- <div>
302
- <Skeleton className="h-4 w-28 mb-1.5" />
303
- <Skeleton className="h-5 w-44 mb-1" />
304
- <Skeleton className="h-5 w-36 mb-1" />
305
- <Skeleton className="h-5 w-28" />
306
- </div>
307
- <div>
308
- <Skeleton className="h-4 w-32 mb-1.5" />
309
- <Skeleton className="h-5 w-44 mb-1" />
310
- <Skeleton className="h-5 w-36 mb-1" />
311
- <Skeleton className="h-5 w-28" />
312
- </div>
313
- </div>
314
- </div>
315
-
316
- <Separator />
317
-
318
- {/* System Information */}
319
- <div className="space-y-4">
320
- <Skeleton className="h-7 w-48 py-2" />
321
- <SkeletonFieldRow />
322
- </div>
323
- </CardContent>
324
- </Card>
325
- </>
326
- );
327
- }
328
-
329
- function SkeletonField() {
330
- return (
331
- <div>
332
- <Skeleton className="h-4 w-24 mb-1.5" />
333
- <Skeleton className="h-5 w-40" />
334
- </div>
335
- );
336
- }
337
-
338
- function SkeletonFieldRow() {
339
- return (
340
- <div className="grid grid-cols-2 gap-x-8 gap-y-4">
341
- <SkeletonField />
342
- <SkeletonField />
343
- </div>
344
- );
345
- }
346
-
347
- function SkeletonSection() {
348
- return (
349
- <div className="space-y-4">
350
- <Skeleton className="h-7 w-48 py-2" />
351
- <SkeletonFieldRow />
352
- <SkeletonFieldRow />
353
- </div>
354
- );
355
- }
@@ -1,304 +0,0 @@
1
- import { useMemo, useState } from "react";
2
- import { Link } from "react-router";
3
- import { AlertCircle, ChevronDown, SearchX } from "lucide-react";
4
- import {
5
- searchAccounts,
6
- fetchDistinctIndustries,
7
- fetchDistinctTypes,
8
- } from "../api/accountSearchService";
9
- import { useAsyncData } from "../../hooks/useAsyncData";
10
- import { fieldValue } from "../../utils/fieldUtils";
11
- import { useObjectSearchParams } from "../../hooks/useObjectSearchParams";
12
- import { Alert, AlertTitle, AlertDescription } from "../../../../components/ui/alert";
13
- import {
14
- Card,
15
- CardContent,
16
- CardHeader,
17
- CardTitle,
18
- } from "../../../../components/ui/card";
19
- import { Button } from "../../../../components/ui/button";
20
- import {
21
- Collapsible,
22
- CollapsibleContent,
23
- CollapsibleTrigger,
24
- } from "../../../../components/ui/collapsible";
25
- import { Skeleton } from "../../../../components/ui/skeleton";
26
- import { FilterProvider, FilterResetButton } from "../../components/FilterContext";
27
- import { SearchFilter } from "../../components/filters/SearchFilter";
28
- import { TextFilter } from "../../components/filters/TextFilter";
29
- import { SelectFilter } from "../../components/filters/SelectFilter";
30
- import { MultiSelectFilter } from "../../components/filters/MultiSelectFilter";
31
- import { NumericRangeFilter } from "../../components/filters/NumericRangeFilter";
32
- import { DateFilter } from "../../components/filters/DateFilter";
33
- import { DateRangeFilter } from "../../components/filters/DateRangeFilter";
34
- import { ActiveFilters } from "../../components/ActiveFilters";
35
- import { SortControl } from "../../components/SortControl";
36
- import type { FilterFieldConfig } from "../../utils/filterUtils";
37
- import type { SortFieldConfig } from "../../utils/sortUtils";
38
- import type { Account_Filter, Account_OrderBy } from "../../../../api/graphql-operations-types";
39
- import type { AccountSearchResult } from "../api/accountSearchService";
40
- import { ObjectBreadcrumb } from "../../components/ObjectBreadcrumb";
41
- import PaginationControls from "../../components/PaginationControls";
42
- import type { PaginationConfig } from "../../hooks/useObjectSearchParams";
43
-
44
- const PAGINATION_CONFIG: PaginationConfig = {
45
- defaultPageSize: 7,
46
- validPageSizes: [7, 14, 28, 42],
47
- };
48
-
49
- type AccountNode = NonNullable<
50
- NonNullable<NonNullable<AccountSearchResult["edges"]>[number]>["node"]
51
- >;
52
-
53
- const FILTER_CONFIGS: FilterFieldConfig[] = [
54
- {
55
- field: "search",
56
- label: "Search",
57
- type: "search",
58
- searchFields: ["Name", "Phone", "Industry"],
59
- placeholder: "Search by name, phone, or industry...",
60
- },
61
- { field: "Name", label: "Account Name", type: "text", placeholder: "Search by name..." },
62
- { field: "Industry", label: "Industry", type: "picklist" },
63
- { field: "Type", label: "Type", type: "multipicklist" },
64
- { field: "AnnualRevenue", label: "Annual Revenue", type: "numeric" },
65
- { field: "CreatedDate", label: "Created Date", type: "datetime" },
66
- { field: "LastModifiedDate", label: "Last Modified Date", type: "datetimerange" },
67
- ];
68
-
69
- const ACCOUNT_SORT_CONFIGS: SortFieldConfig<keyof Account_OrderBy>[] = [
70
- { field: "Name", label: "Name" },
71
- { field: "AnnualRevenue", label: "Annual Revenue" },
72
- { field: "Industry", label: "Industry" },
73
- { field: "CreatedDate", label: "Created Date" },
74
- ];
75
-
76
- // -- Component --------------------------------------------------------------
77
-
78
- export default function AccountSearch() {
79
- const [filtersOpen, setFiltersOpen] = useState(true);
80
- const { data: industryOptions } = useAsyncData(fetchDistinctIndustries, []);
81
- const { data: typeOptions } = useAsyncData(fetchDistinctTypes, []);
82
-
83
- const { filters, sort, query, pagination, resetAll } = useObjectSearchParams<
84
- Account_Filter,
85
- Account_OrderBy
86
- >(FILTER_CONFIGS, ACCOUNT_SORT_CONFIGS, PAGINATION_CONFIG);
87
-
88
- const { data, loading, error } = useAsyncData(
89
- () =>
90
- searchAccounts({
91
- where: query.where,
92
- orderBy: query.orderBy,
93
- first: pagination.pageSize,
94
- after: pagination.afterCursor,
95
- }),
96
- [query.where, query.orderBy, pagination.pageSize, pagination.afterCursor],
97
- );
98
-
99
- const pageInfo = data?.pageInfo;
100
- const totalCount = data?.totalCount;
101
- const hasNextPage = pageInfo?.hasNextPage ?? false;
102
- const hasPreviousPage = pagination.pageIndex > 0;
103
-
104
- const validAccountNodes = useMemo(
105
- () =>
106
- (data?.edges ?? []).reduce<AccountNode[]>((acc, edge) => {
107
- if (edge?.node) acc.push(edge.node);
108
- return acc;
109
- }, []),
110
- [data?.edges],
111
- );
112
-
113
- return (
114
- <div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
115
- <ObjectBreadcrumb listPath="/accounts" listLabel="Accounts" />
116
-
117
- <h1 className="text-2xl font-bold mb-4">Search Accounts</h1>
118
-
119
- <div className="flex flex-col lg:flex-row gap-6">
120
- {/* Sidebar — Filter Panel */}
121
- <aside className="w-full lg:w-80 shrink-0">
122
- <FilterProvider
123
- filters={filters.active}
124
- onFilterChange={filters.set}
125
- onFilterRemove={filters.remove}
126
- onReset={resetAll}
127
- >
128
- <Card>
129
- <Collapsible open={filtersOpen} onOpenChange={setFiltersOpen}>
130
- <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
131
- <CardTitle className="text-base font-semibold">
132
- <h2>Filters</h2>
133
- </CardTitle>
134
- <div className="flex items-center gap-1">
135
- <FilterResetButton variant="destructive" size="sm" />
136
- <CollapsibleTrigger asChild>
137
- <Button variant="ghost" size="icon">
138
- <ChevronDown
139
- className={`h-4 w-4 transition-transform ${filtersOpen ? "" : "-rotate-90"}`}
140
- />
141
- <span className="sr-only">Toggle filters</span>
142
- </Button>
143
- </CollapsibleTrigger>
144
- </div>
145
- </CardHeader>
146
- <CollapsibleContent>
147
- <CardContent className="space-y-1 pt-0">
148
- <SearchFilter
149
- field="search"
150
- label="Search"
151
- placeholder="Search by name, phone, or industry..."
152
- />
153
- <TextFilter field="Name" label="Account Name" placeholder="Search by name..." />
154
- <SelectFilter
155
- field="Industry"
156
- label="Industry"
157
- options={industryOptions ?? []}
158
- />
159
- <MultiSelectFilter field="Type" label="Type" options={typeOptions ?? []} />
160
- <NumericRangeFilter
161
- field="AnnualRevenue"
162
- label="Annual Revenue"
163
- min={0}
164
- max={1_000_000_000_000}
165
- />
166
- <DateFilter field="CreatedDate" label="Created Date" filterType="datetime" />
167
- <DateRangeFilter
168
- field="LastModifiedDate"
169
- label="Last Modified Date"
170
- filterType="datetimerange"
171
- />
172
- </CardContent>
173
- </CollapsibleContent>
174
- </Collapsible>
175
- </Card>
176
- </FilterProvider>
177
- </aside>
178
-
179
- {/* Main area — Sort + Results */}
180
- <div className="flex-1 min-w-0">
181
- {/* Sort control + active filters */}
182
- <div className="flex flex-wrap items-center gap-2 mb-4">
183
- <SortControl
184
- configs={ACCOUNT_SORT_CONFIGS}
185
- sort={sort.current}
186
- onSortChange={sort.set}
187
- />
188
- <ActiveFilters filters={filters.active} onRemove={filters.remove} />
189
- </div>
190
-
191
- <div className="min-h-132">
192
- {/* Loading state */}
193
- {loading && (
194
- <>
195
- <Skeleton className="h-5 w-30 mb-3" />
196
- <div className="divide-y">
197
- {Array.from({ length: pagination.pageSize }, (_, i) => (
198
- <div key={i} className="flex items-center justify-between py-3">
199
- <div className="space-y-2">
200
- <Skeleton className="h-5 w-40" />
201
- <Skeleton className="h-4 w-28" />
202
- </div>
203
- <div className="space-y-2 flex flex-col items-end">
204
- <Skeleton className="h-4 w-24" />
205
- <Skeleton className="h-4 w-20" />
206
- </div>
207
- </div>
208
- ))}
209
- </div>
210
- </>
211
- )}
212
-
213
- {/* Error state */}
214
- {error && (
215
- <>
216
- <p className="text-sm text-muted-foreground mb-3">0 accounts found</p>
217
- <Alert variant="destructive" role="alert">
218
- <AlertCircle />
219
- <AlertTitle>Failed to load accounts</AlertTitle>
220
- <AlertDescription>
221
- Something went wrong while loading accounts. Please try again later.
222
- </AlertDescription>
223
- </Alert>
224
- </>
225
- )}
226
-
227
- {/* Results list */}
228
- {!loading && !error && validAccountNodes.length > 0 && (
229
- <>
230
- <p className="text-sm text-muted-foreground mb-3">
231
- {totalCount != null && (hasNextPage || hasPreviousPage)
232
- ? `${totalCount} account${totalCount !== 1 ? "s" : ""} found`
233
- : `Showing ${validAccountNodes.length} account${validAccountNodes.length !== 1 ? "s" : ""}`}
234
- </p>
235
- <AccountResultsList nodes={validAccountNodes} />
236
- </>
237
- )}
238
-
239
- {/* No results state */}
240
- {!loading && !error && validAccountNodes.length === 0 && (
241
- <div className="flex flex-col items-center justify-center py-16 text-center">
242
- <SearchX className="size-12 text-muted-foreground mb-4" />
243
- <h2 className="text-lg font-semibold mb-1">No accounts found</h2>
244
- <p className="text-sm text-muted-foreground">
245
- Try adjusting your filters or search criteria.
246
- </p>
247
- </div>
248
- )}
249
- </div>
250
-
251
- {/* Pagination — always visible, disabled while loading or on error */}
252
- <PaginationControls
253
- pageIndex={pagination.pageIndex}
254
- hasNextPage={hasNextPage}
255
- hasPreviousPage={hasPreviousPage}
256
- pageSize={pagination.pageSize}
257
- pageSizeOptions={PAGINATION_CONFIG.validPageSizes}
258
- onNextPage={() => {
259
- if (pageInfo?.endCursor) pagination.goToNextPage(pageInfo.endCursor);
260
- }}
261
- onPreviousPage={pagination.goToPreviousPage}
262
- onPageSizeChange={pagination.setPageSize}
263
- disabled={loading || !!error}
264
- />
265
- </div>
266
- </div>
267
- </div>
268
- );
269
- }
270
-
271
- // -- Result Components ------------------------------------------------------
272
-
273
- function AccountResultsList({ nodes }: { nodes: AccountNode[] }) {
274
- return (
275
- <ul className="divide-y">
276
- {nodes.map((node) => (
277
- <AccountResultItem key={node.Id} node={node} />
278
- ))}
279
- </ul>
280
- );
281
- }
282
-
283
- function AccountResultItem({ node }: { node: AccountNode }) {
284
- return (
285
- <li>
286
- <Link
287
- to={`/accounts/${node.Id}`}
288
- className="flex items-center justify-between py-3 px-3 -mx-3 rounded-md transition-colors hover:bg-accent"
289
- >
290
- <div>
291
- <span className="font-medium">{fieldValue(node.Name) ?? "\u2014"}</span>
292
- <p className="text-sm text-muted-foreground">
293
- {[fieldValue(node.Industry), fieldValue(node.Type)].filter(Boolean).join(" \u00B7 ") ||
294
- "\u2014"}
295
- </p>
296
- </div>
297
- <div className="text-right text-sm">
298
- <p>{fieldValue(node.Phone) ?? ""}</p>
299
- <p className="text-muted-foreground">{fieldValue(node.Owner?.Name) ?? ""}</p>
300
- </div>
301
- </Link>
302
- </li>
303
- );
304
- }
@@ -1,34 +0,0 @@
1
- import { useState } from "react";
2
- import { useNavigate } from "react-router";
3
- import { SearchBar } from "../../components/SearchBar";
4
- import { Button } from "../../../../components/ui/button";
5
-
6
- export default function HomePage() {
7
- const navigate = useNavigate();
8
- const [text, setText] = useState("");
9
-
10
- const handleSubmit = (e: React.SyntheticEvent<HTMLFormElement>) => {
11
- e.preventDefault();
12
- const params = text ? `?q=${encodeURIComponent(text)}` : "";
13
- navigate(`/accounts${params}`);
14
- };
15
-
16
- return (
17
- <div className="max-w-2xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
18
- <div className="flex items-center gap-6 mb-6">
19
- <h1 className="text-2xl font-bold">Account Search</h1>
20
- <Button variant="outline" size="sm" onClick={() => navigate("/accounts")}>
21
- Browse All Accounts
22
- </Button>
23
- </div>
24
- <form onSubmit={handleSubmit} className="flex gap-2">
25
- <SearchBar
26
- placeholder="Search by name, phone, or industry..."
27
- value={text}
28
- handleChange={setText}
29
- />
30
- <Button type="submit">Search</Button>
31
- </form>
32
- </div>
33
- );
34
- }