@salesforce/templates 66.17.4 → 66.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/lib/generators/analyticsTemplateGenerator.d.ts +1 -1
  2. package/lib/generators/analyticsTemplateGenerator.js +1 -1
  3. package/lib/generators/analyticsTemplateGenerator.js.map +1 -1
  4. package/lib/generators/apexClassGenerator.d.ts +1 -1
  5. package/lib/generators/apexClassGenerator.js +1 -0
  6. package/lib/generators/apexClassGenerator.js.map +1 -1
  7. package/lib/generators/apexTriggerGenerator.d.ts +1 -1
  8. package/lib/generators/baseGenerator.d.ts +1 -1
  9. package/lib/generators/baseGenerator.js +13 -7
  10. package/lib/generators/baseGenerator.js.map +1 -1
  11. package/lib/generators/digitalExperienceSiteGenerator.d.ts +1 -2
  12. package/lib/generators/digitalExperienceSiteGenerator.js +9 -9
  13. package/lib/generators/digitalExperienceSiteGenerator.js.map +1 -1
  14. package/lib/generators/flexipageGenerator.d.ts +1 -2
  15. package/lib/generators/flexipageGenerator.js +5 -7
  16. package/lib/generators/flexipageGenerator.js.map +1 -1
  17. package/lib/generators/lightningAppGenerator.d.ts +1 -1
  18. package/lib/generators/lightningComponentGenerator.d.ts +1 -1
  19. package/lib/generators/lightningEventGenerator.d.ts +1 -1
  20. package/lib/generators/lightningInterfaceGenerator.d.ts +1 -1
  21. package/lib/generators/lightningOutGenerator.d.ts +1 -1
  22. package/lib/generators/lightningOutGenerator.js +21 -5
  23. package/lib/generators/lightningOutGenerator.js.map +1 -1
  24. package/lib/generators/lightningTestGenerator.d.ts +1 -1
  25. package/lib/generators/lightningTestGenerator.js +1 -1
  26. package/lib/generators/lightningTestGenerator.js.map +1 -1
  27. package/lib/generators/projectGenerator.d.ts +1 -1
  28. package/lib/generators/projectGenerator.js +8 -5
  29. package/lib/generators/projectGenerator.js.map +1 -1
  30. package/lib/generators/staticResourceGenerator.d.ts +1 -1
  31. package/lib/generators/uiBundleGenerator.d.ts +1 -1
  32. package/lib/generators/uiBundleGenerator.js +4 -2
  33. package/lib/generators/uiBundleGenerator.js.map +1 -1
  34. package/lib/generators/uiEmbeddingGenerator.d.ts +1 -1
  35. package/lib/generators/uiEmbeddingGenerator.js +2 -1
  36. package/lib/generators/uiEmbeddingGenerator.js.map +1 -1
  37. package/lib/generators/visualforceComponentGenerator.d.ts +1 -1
  38. package/lib/generators/visualforcePageGenerator.d.ts +1 -1
  39. package/lib/i18n/index.js +1 -1
  40. package/lib/i18n/index.js.map +1 -1
  41. package/lib/i18n/localization.js +13 -12
  42. package/lib/i18n/localization.js.map +1 -1
  43. package/lib/index.js.map +1 -1
  44. package/lib/service/gitRepoUtils.d.ts +1 -1
  45. package/lib/service/gitRepoUtils.js +7 -8
  46. package/lib/service/gitRepoUtils.js.map +1 -1
  47. package/lib/service/templateService.d.ts +1 -1
  48. package/lib/service/templateService.js +1 -1
  49. package/lib/service/templateService.js.map +1 -1
  50. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +558 -533
  51. package/lib/templates/project/angularintapp/CHANGELOG.md +8 -0
  52. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +2 -1
  53. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +568 -543
  54. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +4 -4
  55. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/components/ui/icon/icon.ts +44 -0
  56. package/lib/templates/project/angularintapp/package.json +1 -1
  57. package/lib/templates/project/reactexternalapp/CHANGELOG.md +40 -0
  58. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/eslint.config.js +8 -12
  59. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +362 -344
  60. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +5 -5
  61. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  62. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/sonner.tsx +7 -1
  63. package/lib/templates/project/reactexternalapp/package.json +1 -1
  64. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +363 -345
  65. package/lib/templates/project/vueinternalapp/.forceignore +15 -0
  66. package/lib/templates/project/vueinternalapp/.husky/pre-commit +4 -0
  67. package/lib/templates/project/vueinternalapp/.prettierignore +11 -0
  68. package/lib/templates/project/vueinternalapp/.prettierrc +17 -0
  69. package/lib/templates/project/vueinternalapp/CHANGELOG.md +5375 -0
  70. package/lib/templates/project/vueinternalapp/PRD.md +35 -0
  71. package/lib/templates/project/vueinternalapp/README.md +125 -0
  72. package/lib/templates/project/vueinternalapp/_p_/_m_/_ps_/vueinternalapp_Access.permissionset-meta.xml +13 -0
  73. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.forceignore +15 -0
  74. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.graphqlrc.yml +2 -0
  75. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.prettierignore +9 -0
  76. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/.prettierrc +11 -0
  77. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/README.md +35 -0
  78. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/codegen.yml +95 -0
  79. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/components.json +19 -0
  80. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/e2e/app.spec.ts +17 -0
  81. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/eslint.config.js +124 -0
  82. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/index.html +12 -0
  83. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/package-lock.json +15530 -0
  84. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/package.json +73 -0
  85. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/playwright.config.ts +24 -0
  86. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +71 -0
  87. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/scripts/rewrite-e2e-assets.mjs +23 -0
  88. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/App.vue +5 -0
  89. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/apiUtils.ts +56 -0
  90. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/orgApiVersionService.ts +37 -0
  91. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/searchableContentTypesService.ts +119 -0
  92. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/channelResolver.ts +40 -0
  93. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/cmsQueryFragment.ts +108 -0
  94. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/composables/useSearchableContentTypes.ts +132 -0
  95. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeSessionCache.ts +134 -0
  96. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeUtils.ts +40 -0
  97. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/index.ts +55 -0
  98. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/parseResponse.ts +65 -0
  99. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/searchChannel.ts +31 -0
  100. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/types.ts +66 -0
  101. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/registry.ts +38 -0
  102. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/index.ts +19 -0
  103. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/parseResponse.ts +55 -0
  104. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/queryFragment.ts +141 -0
  105. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/types.ts +103 -0
  106. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +81 -0
  107. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +136 -0
  108. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.types.ts +18 -0
  109. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.vue +73 -0
  110. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.types.ts +24 -0
  111. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.vue +263 -0
  112. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.vue +200 -0
  113. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.vue +99 -0
  114. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.vue +204 -0
  115. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.vue +180 -0
  116. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.vue +91 -0
  117. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.vue +56 -0
  118. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.vue +55 -0
  119. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.vue +59 -0
  120. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterField.vue +63 -0
  121. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.vue +31 -0
  122. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/FilterContext.ts +45 -0
  123. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/FilterProvider.vue +23 -0
  124. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/FilterResetButton.vue +17 -0
  125. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/PicklistField.vue +35 -0
  126. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.vue +47 -0
  127. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.vue +144 -0
  128. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/FilterFieldWrapper.vue +23 -0
  129. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.vue +95 -0
  130. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.vue +117 -0
  131. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.vue +44 -0
  132. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.vue +49 -0
  133. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/CmsResultRow.vue +160 -0
  134. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.vue +102 -0
  135. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/RenderVNode.ts +10 -0
  136. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/resolveResultRenderer.ts +41 -0
  137. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/composables/useAsyncData.ts +66 -0
  138. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/composables/useDistinctValues.ts +67 -0
  139. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/composables/useSearch.ts +906 -0
  140. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +88 -0
  141. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/constants.ts +8 -0
  142. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +115 -0
  143. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  144. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +100 -0
  145. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +375 -0
  146. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  147. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  148. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +304 -0
  149. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  150. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/getAccountDetail.graphql +121 -0
  151. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/api/graphqlClient.ts +44 -0
  152. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/appLayout.vue +153 -0
  153. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.vue +76 -0
  154. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailContent.vue +124 -0
  155. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailError.vue +28 -0
  156. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailNotFound.vue +22 -0
  157. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/AccountDetailSkeleton.vue +57 -0
  158. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/DetailSection.vue +25 -0
  159. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/FieldItem.vue +17 -0
  160. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/FieldRow.vue +5 -0
  161. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/SkeletonFieldRow.vue +12 -0
  162. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/TelephoneField.vue +7 -0
  163. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/account/types.ts +42 -0
  164. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/alerts/status-alert.vue +59 -0
  165. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/layouts/card-layout.vue +30 -0
  166. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/Alert.vue +21 -0
  167. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/AlertAction.vue +17 -0
  168. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/AlertDescription.vue +22 -0
  169. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/AlertTitle.vue +22 -0
  170. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/alert/index.ts +25 -0
  171. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/Avatar.vue +23 -0
  172. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/AvatarFallback.vue +31 -0
  173. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/AvatarImage.vue +16 -0
  174. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/avatar/index.ts +3 -0
  175. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button/Button.vue +33 -0
  176. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button/index.ts +43 -0
  177. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/Card.vue +29 -0
  178. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardAction.vue +22 -0
  179. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardContent.vue +17 -0
  180. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardDescription.vue +17 -0
  181. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardFooter.vue +22 -0
  182. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardHeader.vue +22 -0
  183. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/CardTitle.vue +22 -0
  184. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/card/index.ts +7 -0
  185. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/checkbox/Checkbox.vue +43 -0
  186. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/checkbox/index.ts +1 -0
  187. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/Collapsible.vue +19 -0
  188. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/CollapsibleContent.vue +12 -0
  189. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
  190. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/collapsible/index.ts +3 -0
  191. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/Dialog.vue +15 -0
  192. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogClose.vue +12 -0
  193. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogContent.vue +59 -0
  194. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogDescription.vue +31 -0
  195. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogFooter.vue +33 -0
  196. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogHeader.vue +17 -0
  197. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogOverlay.vue +31 -0
  198. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogPortal.vue +12 -0
  199. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogTitle.vue +26 -0
  200. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/DialogTrigger.vue +12 -0
  201. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dialog/index.ts +10 -0
  202. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
  203. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +51 -0
  204. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuContent.vue +47 -0
  205. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
  206. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuItem.vue +44 -0
  207. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +30 -0
  208. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuPortal.vue +12 -0
  209. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
  210. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +52 -0
  211. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +26 -0
  212. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +19 -0
  213. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
  214. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +37 -0
  215. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +38 -0
  216. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
  217. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/dropdown-menu/index.ts +15 -0
  218. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/Field.vue +27 -0
  219. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldContent.vue +22 -0
  220. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldDescription.vue +24 -0
  221. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldError.vue +48 -0
  222. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldGroup.vue +22 -0
  223. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldLabel.vue +24 -0
  224. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldLegend.vue +29 -0
  225. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldSeparator.vue +31 -0
  226. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldSet.vue +22 -0
  227. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/FieldTitle.vue +22 -0
  228. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/field/index.ts +33 -0
  229. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/index.ts +115 -0
  230. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/input/Input.vue +30 -0
  231. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/input/index.ts +1 -0
  232. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/label/Label.vue +29 -0
  233. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/label/index.ts +1 -0
  234. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/Pagination.vue +17 -0
  235. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationContent.vue +15 -0
  236. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationEllipsis.vue +23 -0
  237. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationItem.vue +7 -0
  238. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationLink.vue +31 -0
  239. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationNext.vue +29 -0
  240. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/PaginationPrevious.vue +29 -0
  241. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/pagination/index.ts +7 -0
  242. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/Popover.vue +15 -0
  243. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverAnchor.vue +12 -0
  244. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverContent.vue +44 -0
  245. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverDescription.vue +17 -0
  246. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverHeader.vue +17 -0
  247. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverTitle.vue +14 -0
  248. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/PopoverTrigger.vue +12 -0
  249. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/popover/index.ts +7 -0
  250. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/Select.vue +15 -0
  251. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectContent.vue +65 -0
  252. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectGroup.vue +26 -0
  253. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectItem.vue +41 -0
  254. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectLabel.vue +26 -0
  255. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectScrollDownButton.vue +32 -0
  256. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectScrollUpButton.vue +32 -0
  257. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectSeparator.vue +24 -0
  258. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectTrigger.vue +45 -0
  259. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/SelectValue.vue +12 -0
  260. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/select/index.ts +10 -0
  261. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/separator/Separator.vue +33 -0
  262. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/separator/index.ts +1 -0
  263. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/skeleton/Skeleton.vue +15 -0
  264. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/skeleton/index.ts +1 -0
  265. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/sonner/Sonner.vue +29 -0
  266. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/sonner/index.ts +3 -0
  267. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/spinner/Spinner.vue +17 -0
  268. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/components/ui/spinner/index.ts +1 -0
  269. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/composables/useAsyncData.ts +69 -0
  270. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/index.ts +10 -0
  271. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/lib/utils.ts +6 -0
  272. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/main.ts +6 -0
  273. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.vue +98 -0
  274. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.vue +20 -0
  275. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/NotFound.vue +28 -0
  276. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/pages/SearchPage.vue +17 -0
  277. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/router-utils.ts +32 -0
  278. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/router.ts +51 -0
  279. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/styles/global.css +134 -0
  280. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/test/setup.ts +1 -0
  281. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/types/conversation.ts +54 -0
  282. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/types/globals.d.ts +13 -0
  283. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/src/utils/accountFields.ts +25 -0
  284. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/tsconfig.json +45 -0
  285. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/tsconfig.node.json +13 -0
  286. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  287. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/ui-bundle.json +7 -0
  288. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vite-env.d.ts +14 -0
  289. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vite.config.ts +106 -0
  290. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vitest-env.d.ts +2 -0
  291. package/lib/templates/project/vueinternalapp/_p_/_m_/_w_/_a_/vueinternalapp.uibundle-meta.xml +8 -0
  292. package/lib/templates/project/vueinternalapp/_p_/_m_/applications/vueinternalapp.app-meta.xml +17 -0
  293. package/lib/templates/project/vueinternalapp/config/project-scratch-def.json +13 -0
  294. package/lib/templates/project/vueinternalapp/eslint.config.js +7 -0
  295. package/lib/templates/project/vueinternalapp/jest.config.js +6 -0
  296. package/lib/templates/project/vueinternalapp/package.json +46 -0
  297. package/lib/templates/project/vueinternalapp/scripts/apex/hello.apex +10 -0
  298. package/lib/templates/project/vueinternalapp/scripts/gitignore-templates.json +4 -0
  299. package/lib/templates/project/vueinternalapp/scripts/graphql-search.sh +191 -0
  300. package/lib/templates/project/vueinternalapp/scripts/network-senders.mjs +84 -0
  301. package/lib/templates/project/vueinternalapp/scripts/org-setup-config-schema.mjs +132 -0
  302. package/lib/templates/project/vueinternalapp/scripts/org-setup-dev.mjs +114 -0
  303. package/lib/templates/project/vueinternalapp/scripts/org-setup-url.mjs +108 -0
  304. package/lib/templates/project/vueinternalapp/scripts/org-setup-utils.mjs +569 -0
  305. package/lib/templates/project/vueinternalapp/scripts/org-setup-xml.mjs +283 -0
  306. package/lib/templates/project/vueinternalapp/scripts/org-setup.config.json +9 -0
  307. package/lib/templates/project/vueinternalapp/scripts/org-setup.mjs +2545 -0
  308. package/lib/templates/project/vueinternalapp/scripts/sf-project-setup.mjs +103 -0
  309. package/lib/templates/project/vueinternalapp/scripts/soql/account.soql +6 -0
  310. package/lib/templates/project/vueinternalapp/scripts/validate-org-setup-config.mjs +38 -0
  311. package/lib/templates/project/vueinternalapp/sfdx-project.json +12 -0
  312. package/lib/templates/uiBundles/angularbasic/package-lock.json +558 -533
  313. package/lib/templates/uiBundles/reactbasic/eslint.config.js +8 -12
  314. package/lib/templates/uiBundles/reactbasic/package-lock.json +362 -344
  315. package/lib/templates/uiBundles/reactbasic/package.json +5 -5
  316. package/lib/templates/uiBundles/reactbasic/src/components/ui/button.tsx +1 -1
  317. package/lib/templates/uiBundles/reactbasic/src/components/ui/sonner.tsx +7 -1
  318. package/lib/templates/uiBundles/vuebasic/eslint.config.js +6 -1
  319. package/lib/templates/uiBundles/vuebasic/package-lock.json +339 -321
  320. package/lib/templates/uiBundles/vuebasic/package.json +5 -5
  321. package/lib/utils/createUtil.js +1 -1
  322. package/lib/utils/createUtil.js.map +1 -1
  323. package/lib/utils/types.d.ts +8 -7
  324. package/lib/utils/types.js +4 -4
  325. package/lib/utils/types.js.map +1 -1
  326. package/lib/utils/uiBundleTemplateUtils.js +13 -9
  327. package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
  328. package/package.json +10 -12
@@ -0,0 +1,44 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ Select,
4
+ SelectContent,
5
+ SelectItem,
6
+ SelectTrigger,
7
+ SelectValue,
8
+ } from "../../../../../components/ui/select";
9
+ import { useFilterField } from "../FilterContext";
10
+ import FilterFieldWrapper from "./FilterFieldWrapper.vue";
11
+
12
+ const ALL_VALUE = "__all__";
13
+
14
+ const props = defineProps<{
15
+ field: string;
16
+ label: string;
17
+ options: Array<{ value: string; label: string }>;
18
+ helpText?: string;
19
+ }>();
20
+
21
+ const { value, onChange } = useFilterField(() => props.field);
22
+ const id = `filter-${props.field}`;
23
+
24
+ const onValueChange = (v: unknown) => {
25
+ if (v === ALL_VALUE) onChange(undefined);
26
+ else onChange({ field: props.field, label: props.label, type: "picklist", value: String(v) });
27
+ };
28
+ </script>
29
+
30
+ <template>
31
+ <FilterFieldWrapper :label="label" :html-for="id" :help-text="helpText">
32
+ <Select :model-value="value?.value ?? ALL_VALUE" @update:model-value="onValueChange">
33
+ <SelectTrigger :id="id" class="w-full">
34
+ <SelectValue :placeholder="`Select ${label.toLowerCase()}`" />
35
+ </SelectTrigger>
36
+ <SelectContent>
37
+ <SelectItem :value="ALL_VALUE">All</SelectItem>
38
+ <SelectItem v-for="opt in options" :key="opt.value" :value="opt.value">
39
+ {{ opt.label }}
40
+ </SelectItem>
41
+ </SelectContent>
42
+ </Select>
43
+ </FilterFieldWrapper>
44
+ </template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ import { ref, watch } from "vue";
3
+ import { Input } from "../../../../../components/ui/input";
4
+ import { useFilterField } from "../FilterContext";
5
+ import FilterFieldWrapper from "./FilterFieldWrapper.vue";
6
+ import { debounce, FILTER_DEBOUNCE_MS } from "../../../utils/debounce";
7
+
8
+ const props = defineProps<{
9
+ field: string;
10
+ label: string;
11
+ placeholder?: string;
12
+ helpText?: string;
13
+ }>();
14
+
15
+ const { value, onChange } = useFilterField(() => props.field);
16
+ const draft = ref<string>(value.value?.value ?? "");
17
+
18
+ // One stable debounced caller; it always reads the latest props/onChange.
19
+ const emitDebounced = debounce((next: string) => {
20
+ if (next === "") onChange(undefined);
21
+ else onChange({ field: props.field, label: props.label, type: "text", value: next });
22
+ }, FILTER_DEBOUNCE_MS);
23
+
24
+ watch(
25
+ () => value.value?.value,
26
+ (v) => {
27
+ draft.value = v ?? "";
28
+ },
29
+ );
30
+
31
+ const onInput = (next: string | number | undefined) => {
32
+ const text = String(next ?? "");
33
+ draft.value = text;
34
+ emitDebounced(text);
35
+ };
36
+ const id = `filter-${props.field}`;
37
+ </script>
38
+
39
+ <template>
40
+ <FilterFieldWrapper :label="label" :html-for="id" :help-text="helpText">
41
+ <Input
42
+ :id="id"
43
+ type="text"
44
+ :model-value="draft"
45
+ :placeholder="placeholder"
46
+ @update:model-value="onInput"
47
+ />
48
+ </FilterFieldWrapper>
49
+ </template>
@@ -0,0 +1,160 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Per-node row for a CMS source. Used by both the per-source section
4
+ * (`SearchResults`) and the merged grid (`MergedSearchResults`) via the shared
5
+ * `resolveResultRenderer` whenever `source.kind === "cms"`.
6
+ *
7
+ * Renders a title, a published-date subtitle, an optional content-type badge,
8
+ * and a vue-router `<RouterLink>` when a route can be built.
9
+ *
10
+ * Link target: `source.routePattern` tokens `:id` (managedContentId), `:key`
11
+ * (managedContentKey), `:contentType` (contentType). No routePattern -> a plain
12
+ * (non-linked) row.
13
+ *
14
+ * The content-type label is rendered only when its FQN passes `isValidCmsFqn`.
15
+ */
16
+ import { computed } from "vue";
17
+ import { RouterLink } from "vue-router";
18
+ import type { CmsSourceConfig, CmsSearchItem } from "../../adapters/cms/types";
19
+ import { formatContentTypeLabel, isValidCmsFqn } from "../../adapters/cms/contentTypeUtils";
20
+
21
+ const EM_BLOCK_SPLIT = /(<(?:em)>[\s\S]*?<\/(?:em)>)/g;
22
+ const EM_BLOCK_EXEC = /^<(?:em)>([\s\S]*?)<\/(?:em)>$/;
23
+ const STRAY_TAG = /<\/?[a-zA-Z][^>]*>/g;
24
+ const ROUTE_TOKEN = /:([A-Za-z_][A-Za-z0-9_]*)/g;
25
+
26
+ /** Formats an ISO date string for display; echoes the raw string on failure. */
27
+ function formatPublishedDate(dateStr: string): string {
28
+ const date = new Date(dateStr);
29
+ if (isNaN(date.getTime())) return dateStr;
30
+ return date.toLocaleDateString(undefined, {
31
+ year: "numeric",
32
+ month: "short",
33
+ day: "numeric",
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Substitutes `:id` / `:key` / `:contentType` tokens in a route pattern with
39
+ * the item's values (URL-encoded). Returns `null` if a required token has no
40
+ * value.
41
+ */
42
+ function resolveRoute(pattern: string, item: CmsSearchItem): string | null {
43
+ const tokens: Record<string, string | undefined> = {
44
+ id: item.managedContentId,
45
+ key: item.managedContentKey,
46
+ contentType: item.contentType,
47
+ };
48
+ let failed = false;
49
+ const out = pattern.replace(ROUTE_TOKEN, (_match, token: string) => {
50
+ const value = tokens[token];
51
+ if (value == null || value === "") {
52
+ failed = true;
53
+ return "";
54
+ }
55
+ return encodeURIComponent(value);
56
+ });
57
+ return failed ? null : out;
58
+ }
59
+
60
+ /**
61
+ * - Decodes every HTML entity the browser knows (named + numeric).
62
+ * - Runs twice to unwrap the double-encoding CMS search sometimes returns.
63
+ */
64
+ function decodeEntities(input: string): string {
65
+ if (typeof document === "undefined") return input;
66
+ const el = document.createElement("textarea");
67
+ const pass = (s: string) => {
68
+ el.innerHTML = s;
69
+ return el.value;
70
+ };
71
+ return pass(pass(input));
72
+ }
73
+
74
+ /** A snippet segment: plain text or a highlighted (`<em>`) run. */
75
+ interface Segment {
76
+ text: string;
77
+ highlight: boolean;
78
+ }
79
+
80
+ /**
81
+ * Parses a snippet that may contain `<em>…</em>` segments into highlighted
82
+ * segments, and strips any other HTML tags so their content renders as plain
83
+ * text. Rendered through text interpolation, so no HTML is ever injected.
84
+ */
85
+ function highlightSegments(snippet: string): Segment[] {
86
+ const decoded = decodeEntities(snippet);
87
+ return decoded.split(EM_BLOCK_SPLIT).map((part) => {
88
+ const emphasisMatch = EM_BLOCK_EXEC.exec(part);
89
+ if (emphasisMatch) return { text: emphasisMatch[1].replace(STRAY_TAG, ""), highlight: true };
90
+ return { text: part.replace(STRAY_TAG, ""), highlight: false };
91
+ });
92
+ }
93
+
94
+ function toPlainText(raw: string): string {
95
+ return decodeEntities(raw).replace(STRAY_TAG, "");
96
+ }
97
+
98
+ const props = defineProps<{ node: unknown; source: CmsSourceConfig }>();
99
+
100
+ const item = computed(() => props.node as CmsSearchItem);
101
+ const titleSegments = computed(() => (item.value.title ? highlightSegments(item.value.title) : []));
102
+ const snippetSegments = computed(() =>
103
+ item.value.highlightedSnippet ? highlightSegments(item.value.highlightedSnippet) : [],
104
+ );
105
+ const subtitle = computed(() => {
106
+ const publishedDate = item.value.managedContentChannelDeliveryDetails?.[0]?.publishedDate;
107
+ const showType =
108
+ typeof item.value.contentType === "string" && isValidCmsFqn(item.value.contentType);
109
+ const parts: string[] = [];
110
+ if (showType) parts.push(formatContentTypeLabel(item.value.contentType));
111
+ if (publishedDate) parts.push(`Published: ${formatPublishedDate(publishedDate)}`);
112
+ return parts.join(" · ");
113
+ });
114
+ // Only render a drill-down link when the source explicitly configures a
115
+ // routePattern. Without one, content rows render as plain (non-linked) rows.
116
+ const href = computed(() =>
117
+ props.source.routePattern ? resolveRoute(props.source.routePattern, item.value) : null,
118
+ );
119
+ const linkLabel = computed(
120
+ () => `View content: ${item.value.title ? toPlainText(item.value.title) : "content"}`,
121
+ );
122
+ </script>
123
+
124
+ <template>
125
+ <component
126
+ :is="href ? RouterLink : 'div'"
127
+ v-bind="
128
+ href
129
+ ? {
130
+ to: href,
131
+ class: 'block hover:bg-accent rounded-md px-3 -mx-3 py-1 transition-colors',
132
+ 'aria-label': linkLabel,
133
+ }
134
+ : { class: 'px-3 -mx-3 py-1' }
135
+ "
136
+ >
137
+ <span class="font-medium">
138
+ <template v-if="titleSegments.length > 0">
139
+ <template v-for="(seg, i) in titleSegments" :key="i">
140
+ <mark
141
+ v-if="seg.highlight"
142
+ class="bg-yellow-200 dark:bg-yellow-700/60 rounded-sm px-0.5"
143
+ >{{ seg.text }}</mark
144
+ >
145
+ <template v-else>{{ seg.text }}</template>
146
+ </template>
147
+ </template>
148
+ <template v-else>—</template>
149
+ </span>
150
+ <p v-if="snippetSegments.length > 0" class="text-sm text-neutral-600 dark:text-neutral-300">
151
+ <template v-for="(seg, i) in snippetSegments" :key="i">
152
+ <mark v-if="seg.highlight" class="bg-yellow-200 dark:bg-yellow-700/60 rounded-sm px-0.5">{{
153
+ seg.text
154
+ }}</mark>
155
+ <template v-else>{{ seg.text }}</template>
156
+ </template>
157
+ </p>
158
+ <p v-if="subtitle" class="text-sm text-neutral-600 dark:text-neutral-300">{{ subtitle }}</p>
159
+ </component>
160
+ </template>
@@ -0,0 +1,102 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * Default per-node row used when no `renderResult` is supplied for a source.
4
+ *
5
+ * Layout:
6
+ * - Title: first entry in `displayFields` (preferring displayValue).
7
+ * - Subtitle: remaining display fields joined with " · ".
8
+ * - When `routePattern` is configured on the source, the row is wrapped in a
9
+ * vue-router `<RouterLink>` whose `to` is built by substituting `:fieldName`
10
+ * tokens with the corresponding field values (special token `:id` resolves
11
+ * to the configured `idField`, default "Id").
12
+ */
13
+ import { computed } from "vue";
14
+ import { RouterLink } from "vue-router";
15
+ import { fieldValue } from "../../utils/fieldUtils";
16
+ import type { DisplayField, SObjectSourceConfig } from "../../types";
17
+
18
+ const ROUTE_TOKEN = /:([A-Za-z_][A-Za-z0-9_]*)/g;
19
+
20
+ function fieldName(f: DisplayField): string {
21
+ return typeof f === "string" ? f : f.name;
22
+ }
23
+
24
+ /** Resolves a single dot-path against a node, returning a string or null. */
25
+ function readPath(node: unknown, path: string): string | null {
26
+ if (!node || typeof node !== "object") return null;
27
+ const parts = path.split(".");
28
+ let cursor: unknown = node;
29
+ for (let i = 0; i < parts.length - 1; i++) {
30
+ if (!cursor || typeof cursor !== "object") return null;
31
+ cursor = (cursor as Record<string, unknown>)[parts[i]];
32
+ }
33
+ const leaf = (cursor as Record<string, unknown> | null)?.[parts[parts.length - 1]];
34
+ if (leaf == null) return null;
35
+ if (typeof leaf === "object") {
36
+ return fieldValue(leaf as { value?: unknown; displayValue?: string | null });
37
+ }
38
+ return String(leaf);
39
+ }
40
+
41
+ /** Reads the user-facing string for a top-level display field. */
42
+ function readDisplayField(node: unknown, field: DisplayField): string | null {
43
+ if (typeof field === "string") return readPath(node, field);
44
+ if ("raw" in field) return readPath(node, field.name);
45
+ // Relationship: prefer the first scalar subfield's display value.
46
+ const sub = field.subfields[0];
47
+ if (!sub) return null;
48
+ const subName = fieldName(sub);
49
+ return readPath(node, `${field.name}.${subName}`);
50
+ }
51
+
52
+ /** Substitutes `:fieldName` tokens in routePattern with node values. */
53
+ function resolveRoute(pattern: string, node: unknown, idField: string): string | null {
54
+ let failed = false;
55
+ const out = pattern.replace(ROUTE_TOKEN, (_, token) => {
56
+ const path = token === "id" ? idField : token;
57
+ const value = readPath(node, path);
58
+ if (value == null) {
59
+ failed = true;
60
+ return "";
61
+ }
62
+ return encodeURIComponent(value);
63
+ });
64
+ return failed ? null : out;
65
+ }
66
+
67
+ const props = defineProps<{ node: unknown; source: SObjectSourceConfig }>();
68
+
69
+ const idField = computed(() => props.source.idField ?? "Id");
70
+ const title = computed(() => {
71
+ const titleField = props.source.displayFields[0];
72
+ return titleField ? readDisplayField(props.node, titleField) : null;
73
+ });
74
+ const subtitle = computed(() =>
75
+ props.source.displayFields
76
+ .slice(1)
77
+ .map((f) => readDisplayField(props.node, f))
78
+ .filter((s): s is string => s != null && s !== "")
79
+ .join(" · "),
80
+ );
81
+ const href = computed(() =>
82
+ props.source.routePattern
83
+ ? resolveRoute(props.source.routePattern, props.node, idField.value)
84
+ : null,
85
+ );
86
+ </script>
87
+
88
+ <template>
89
+ <RouterLink
90
+ v-if="href"
91
+ :to="href"
92
+ class="block hover:bg-accent rounded-md px-3 -mx-3 py-1 transition-colors"
93
+ :aria-label="`View: ${title ?? 'result'}`"
94
+ >
95
+ <span class="font-medium">{{ title ?? "—" }}</span>
96
+ <p v-if="subtitle" class="text-sm text-neutral-600 dark:text-neutral-300">{{ subtitle }}</p>
97
+ </RouterLink>
98
+ <div v-else class="px-3 -mx-3 py-1">
99
+ <span class="font-medium">{{ title ?? "—" }}</span>
100
+ <p v-if="subtitle" class="text-sm text-neutral-600 dark:text-neutral-300">{{ subtitle }}</p>
101
+ </div>
102
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { FunctionalComponent, VNodeChild } from "vue";
2
+
3
+ /**
4
+ * Tiny functional component that invokes a render function and returns its
5
+ * output. Lets templates mount the `(node) => VNodeChild` renderers that
6
+ * `renderResult` / `renderFilters` / `renderHeader` accept.
7
+ */
8
+ export const RenderVNode: FunctionalComponent<{ render: () => VNodeChild }> = (props) =>
9
+ props.render() as never;
10
+ RenderVNode.props = ["render"];
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Single source of truth for choosing how one source's result node is rendered.
3
+ *
4
+ * Every result layout (`SearchResults`, `MergedSearchResults`, and any future
5
+ * grid/list) MUST resolve its per-node renderer through this helper so the
6
+ * kind-aware default can never be missed in one mode. The rule, in order:
7
+ *
8
+ * 1. A `renderResult[source.key]` config override wins in EVERY mode —
9
+ * including `false`, which hides the source entirely.
10
+ * 2. Otherwise `source.kind === "cms"` -> {@link CmsResultRow}.
11
+ * 3. Otherwise (SObject) -> {@link DefaultResultRow}.
12
+ *
13
+ * Returning the same union the callers already use (`renderer | false`) lets a
14
+ * component skip a hidden source without special-casing.
15
+ */
16
+
17
+ import { h, type VNodeChild } from "vue";
18
+ import type { SourceConfig } from "../../types";
19
+ import DefaultResultRow from "./DefaultResultRow.vue";
20
+ import CmsResultRow from "./CmsResultRow.vue";
21
+
22
+ /** A per-node renderer (Vue render function), or `false` to hide the source's results. */
23
+ export type ResultRenderer = ((node: unknown) => VNodeChild) | false;
24
+
25
+ /**
26
+ * Resolves the renderer for one source. See the module doc for the precedence
27
+ * rules. `renderResult` is the optional per-source override map from `<Search>`.
28
+ */
29
+ export function resolveResultRenderer(
30
+ source: SourceConfig,
31
+ renderResult?: Record<string, ResultRenderer>,
32
+ ): ResultRenderer {
33
+ const override = renderResult?.[source.key];
34
+ // A config override wins in every mode — including `false` (hide).
35
+ if (override !== undefined) return override;
36
+
37
+ if (source.kind === "cms") {
38
+ return (node: unknown) => h(CmsResultRow, { node, source });
39
+ }
40
+ return (node: unknown) => h(DefaultResultRow, { node, source });
41
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Copyright (c) 2026, Salesforce, Inc.,
3
+ * All rights reserved.
4
+ * For full license text, see the LICENSE.txt file
5
+ */
6
+ import type { Ref, WatchSource } from "vue";
7
+ import { ref, shallowRef, watch } from "vue";
8
+
9
+ /** Reactive async-data snapshot: current data, loading, and error. */
10
+ export interface AsyncData<T> {
11
+ /** Latest successful result. Kept visible during a refetch. */
12
+ data: Ref<T | null>;
13
+ /** True while a fetch for the current args is in flight. */
14
+ loading: Ref<boolean>;
15
+ /** Error message from the most recent failed fetch, else null. */
16
+ error: Ref<string | null>;
17
+ }
18
+
19
+ /**
20
+ * Runs an async `fetcher` immediately and again whenever `source` changes,
21
+ * exposing the result as reactive refs. Stale responses (the source changed
22
+ * during a fetch, or the component unmounted) are dropped via a generation
23
+ * counter, so only the latest in-flight request can write state.
24
+ *
25
+ * Shipped with the feature (like the React feature's own hook) rather than
26
+ * re-exported from the base app, so the search library works in host apps that
27
+ * don't include base-vue-app's `composables/useAsyncData`.
28
+ */
29
+ export function useAsyncData<TArgs, T>(
30
+ source: WatchSource<TArgs>,
31
+ fetcher: (args: TArgs) => Promise<T>,
32
+ ): AsyncData<T> {
33
+ const data = shallowRef<T | null>(null);
34
+ const loading = ref<boolean>(true);
35
+ const error = ref<string | null>(null);
36
+
37
+ let generation = 0;
38
+
39
+ const run = (args: TArgs): void => {
40
+ const current = ++generation;
41
+ loading.value = true;
42
+ error.value = null;
43
+
44
+ fetcher(args)
45
+ .then((result) => {
46
+ if (current === generation) {
47
+ data.value = result;
48
+ }
49
+ })
50
+ .catch((err: unknown) => {
51
+ console.error(err);
52
+ if (current === generation) {
53
+ error.value = err instanceof Error ? err.message : "An error occurred";
54
+ }
55
+ })
56
+ .finally(() => {
57
+ if (current === generation) {
58
+ loading.value = false;
59
+ }
60
+ });
61
+ };
62
+
63
+ watch(source, (args) => run(args), { immediate: true, deep: true });
64
+
65
+ return { data, loading, error };
66
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Caches and serves distinct picklist values fetched via the GraphQL
3
+ * aggregate API. The cache key is `${objectName}.${fieldName}`; entries
4
+ * persist for the lifetime of the page so repeated mounts of the same
5
+ * picklist filter share the same response.
6
+ *
7
+ * Pass `null` to short-circuit the fetch (e.g. when inline options are
8
+ * available on the filter config). The query may be a ref/getter; the fetch
9
+ * re-runs when the resolved cache key changes.
10
+ */
11
+
12
+ import { ref, toValue, watch, type MaybeRefOrGetter, type Ref } from "vue";
13
+ import { fetchDistinctValues, type PicklistOption } from "../api/distinctValuesService";
14
+
15
+ const cache = new Map<string, PicklistOption[]>();
16
+ const inflight = new Map<string, Promise<PicklistOption[]>>();
17
+
18
+ export interface DistinctValuesQuery {
19
+ objectName: string;
20
+ fieldName: string;
21
+ }
22
+
23
+ export function useDistinctValues(
24
+ query: MaybeRefOrGetter<DistinctValuesQuery | null>,
25
+ ): Ref<PicklistOption[] | null> {
26
+ const keyOf = (q: DistinctValuesQuery | null) => (q ? `${q.objectName}.${q.fieldName}` : null);
27
+ const options = ref<PicklistOption[] | null>(null) as Ref<PicklistOption[] | null>;
28
+ const initialKey = keyOf(toValue(query));
29
+ if (initialKey) options.value = cache.get(initialKey) ?? null;
30
+
31
+ watch(
32
+ () => keyOf(toValue(query)),
33
+ (cacheKey, _prev, onCleanup) => {
34
+ const q = toValue(query);
35
+ if (!q || !cacheKey) return;
36
+ const cached = cache.get(cacheKey);
37
+ if (cached) {
38
+ options.value = cached;
39
+ return;
40
+ }
41
+ let cancelled = false;
42
+ onCleanup(() => {
43
+ cancelled = true;
44
+ });
45
+ const existing = inflight.get(cacheKey);
46
+ const promise =
47
+ existing ??
48
+ fetchDistinctValues(q.objectName, q.fieldName).then((result) => {
49
+ cache.set(cacheKey, result);
50
+ inflight.delete(cacheKey);
51
+ return result;
52
+ });
53
+ if (!existing) inflight.set(cacheKey, promise);
54
+ promise
55
+ .then((result) => {
56
+ if (!cancelled) options.value = result;
57
+ })
58
+ .catch((err: unknown) => {
59
+ inflight.delete(cacheKey);
60
+ console.error(`Failed to fetch distinct values for ${cacheKey}:`, err);
61
+ });
62
+ },
63
+ { immediate: true },
64
+ );
65
+
66
+ return options;
67
+ }