@salesforce/ui-bundle-template-feature-react-global-search 1.117.2
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.
- package/LICENSE.txt +82 -0
- package/README.md +250 -0
- package/dist/.forceignore +15 -0
- package/dist/.husky/pre-commit +4 -0
- package/dist/.prettierignore +11 -0
- package/dist/.prettierrc +17 -0
- package/dist/AGENT.md +193 -0
- package/dist/CHANGELOG.md +2128 -0
- package/dist/README.md +28 -0
- package/dist/config/project-scratch-def.json +13 -0
- package/dist/eslint.config.js +7 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/.forceignore +15 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/.graphqlrc.yml +2 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/.prettierignore +9 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/.prettierrc +11 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/CHANGELOG.md +10 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/README.md +75 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/codegen.yml +95 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/components.json +18 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/e2e/app.spec.ts +17 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/eslint.config.js +169 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/feature-react-global-search.uibundle-meta.xml +7 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/index.html +12 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/package.json +70 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/playwright.config.ts +24 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/scripts/get-graphql-schema.mjs +68 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/scripts/rewrite-e2e-assets.mjs +23 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/api/graphqlClient.ts +25 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/app.tsx +17 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/appLayout.tsx +83 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/icons/book.svg +3 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/icons/copy.svg +4 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/icons/rocket.svg +3 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/icons/star.svg +3 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/images/codey-1.png +0 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/images/codey-2.png +0 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/images/codey-3.png +0 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/assets/images/vibe-codey.svg +194 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/alerts/status-alert.tsx +49 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/layouts/card-layout.tsx +29 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/alert.tsx +76 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/badge.tsx +48 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/breadcrumb.tsx +109 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/button.tsx +67 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/calendar.tsx +232 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/card.tsx +103 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/checkbox.tsx +32 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/collapsible.tsx +33 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/datePicker.tsx +127 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/dialog.tsx +162 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/field.tsx +237 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/index.ts +84 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/input.tsx +19 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/label.tsx +22 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/pagination.tsx +132 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/popover.tsx +89 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/select.tsx +193 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/separator.tsx +26 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/skeleton.tsx +14 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/sonner.tsx +20 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/spinner.tsx +16 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/table.tsx +114 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/tabs.tsx +88 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/objectDetailService.ts +102 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/objectInfoGraphQLService.ts +137 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/objectInfoService.ts +95 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/recordListGraphQLService.ts +364 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailFields.tsx +55 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailForm.tsx +146 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailHeader.tsx +34 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailLayoutSections.tsx +80 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/Section.tsx +108 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/SectionRow.tsx +20 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/UiApiDetailForm.tsx +140 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FieldValueDisplay.tsx +73 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedAddress.tsx +29 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedEmail.tsx +17 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedPhone.tsx +24 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedText.tsx +11 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedUrl.tsx +29 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FilterField.tsx +54 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FilterInput.tsx +55 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FilterSelect.tsx +72 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FiltersPanel.tsx +380 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/forms/filters-form.tsx +114 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/forms/submit-button.tsx +47 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/GlobalSearchInput.tsx +114 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/ResultCardFields.tsx +71 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchHeader.tsx +31 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchPagination.tsx +144 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchResultCard.tsx +138 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchResultsPanel.tsx +197 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/shared/LoadingFallback.tsx +61 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/constants.ts +39 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/filters/FilterInput.tsx +55 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/filters/FilterSelect.tsx +72 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/form.tsx +209 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useObjectInfoBatch.ts +72 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useObjectSearchData.ts +174 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useRecordDetailLayout.ts +137 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useRecordListGraphQL.ts +135 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/pages/DetailPage.tsx +109 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/pages/GlobalSearch.tsx +235 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/filters/filters.ts +121 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/filters/picklist.ts +6 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/objectInfo/objectInfo.ts +49 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/recordDetail/recordDetail.ts +61 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/schema.d.ts +200 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/search/searchResults.ts +229 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/apiUtils.ts +59 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/cacheUtils.ts +76 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/debounce.ts +90 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/fieldUtils.ts +354 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/fieldValueExtractor.ts +67 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/filterUtils.ts +32 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/formDataTransformUtils.ts +260 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/formUtils.ts +142 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/graphQLNodeFieldUtils.ts +186 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/graphQLObjectInfoAdapter.ts +77 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/graphQLRecordAdapter.ts +90 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/layoutTransformUtils.ts +236 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/linkUtils.ts +14 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/paginationUtils.ts +49 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/recordUtils.ts +159 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/sanitizationUtils.ts +50 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/index.ts +120 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/lib/utils.ts +6 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/navigationMenu.tsx +80 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/pages/Home.tsx +13 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/pages/NotFound.tsx +18 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/router-utils.tsx +35 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/routes.tsx +44 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/src/styles/global.css +135 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/tsconfig.json +42 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/tsconfig.node.json +13 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/ui-bundle.json +7 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/vite-env.d.ts +1 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/vite.config.ts +106 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/vitest-env.d.ts +2 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/vitest.config.ts +11 -0
- package/dist/force-app/main/default/uiBundles/feature-react-global-search/vitest.setup.ts +1 -0
- package/dist/jest.config.js +6 -0
- package/dist/package-lock.json +9995 -0
- package/dist/package.json +40 -0
- package/dist/scripts/apex/hello.apex +10 -0
- package/dist/scripts/graphql-search.sh +191 -0
- package/dist/scripts/prepare-import-unique-fields.js +122 -0
- package/dist/scripts/setup-cli.mjs +563 -0
- package/dist/scripts/sf-project-setup.mjs +66 -0
- package/dist/scripts/soql/account.soql +6 -0
- package/dist/sfdx-project.json +12 -0
- package/package.json +53 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/__inherit__appLayout.tsx +9 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/alerts/__inherit__status-alert.tsx +27 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/layouts/__inherit__card-layout.tsx +9 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__alert.tsx +41 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__button.tsx +45 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__card.tsx +33 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__field.tsx +62 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__input.tsx +5 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__label.tsx +8 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__pagination.tsx +47 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__select.tsx +57 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__skeleton.tsx +5 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/components/ui/__inherit__spinner.tsx +7 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/objectDetailService.ts +102 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/objectInfoGraphQLService.ts +137 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/objectInfoService.ts +95 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/api/recordListGraphQLService.ts +364 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailFields.tsx +55 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailForm.tsx +146 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailHeader.tsx +34 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/DetailLayoutSections.tsx +80 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/Section.tsx +108 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/SectionRow.tsx +20 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/UiApiDetailForm.tsx +140 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FieldValueDisplay.tsx +73 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedAddress.tsx +29 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedEmail.tsx +17 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedPhone.tsx +24 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedText.tsx +11 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/detail/formatted/FormattedUrl.tsx +29 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FilterField.tsx +54 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FilterInput.tsx +55 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FilterSelect.tsx +72 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/filters/FiltersPanel.tsx +380 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/forms/filters-form.tsx +114 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/forms/submit-button.tsx +47 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/GlobalSearchInput.tsx +114 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/ResultCardFields.tsx +71 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchHeader.tsx +31 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchPagination.tsx +144 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchResultCard.tsx +138 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/search/SearchResultsPanel.tsx +197 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/components/shared/LoadingFallback.tsx +61 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/constants.ts +39 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/filters/FilterInput.tsx +55 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/filters/FilterSelect.tsx +72 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/form.tsx +209 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useObjectInfoBatch.ts +72 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useObjectSearchData.ts +174 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useRecordDetailLayout.ts +137 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/hooks/useRecordListGraphQL.ts +135 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/pages/DetailPage.tsx +109 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/pages/GlobalSearch.tsx +235 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/filters/filters.ts +121 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/filters/picklist.ts +6 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/objectInfo/objectInfo.ts +49 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/recordDetail/recordDetail.ts +61 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/schema.d.ts +200 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/types/search/searchResults.ts +229 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/apiUtils.ts +59 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/cacheUtils.ts +76 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/debounce.ts +90 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/fieldUtils.ts +354 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/fieldValueExtractor.ts +67 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/filterUtils.ts +32 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/formDataTransformUtils.ts +260 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/formUtils.ts +142 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/graphQLNodeFieldUtils.ts +186 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/graphQLObjectInfoAdapter.ts +77 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/graphQLRecordAdapter.ts +90 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/layoutTransformUtils.ts +236 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/linkUtils.ts +14 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/paginationUtils.ts +49 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/recordUtils.ts +159 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/features/global-search/utils/sanitizationUtils.ts +50 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/index.ts +120 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/lib/__inherit__utils.ts +5 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/pages/Home.tsx +13 -0
- package/src/force-app/main/default/uiBundles/feature-react-global-search/src/routes.tsx +52 -0
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@salesforce/ui-bundle-template-feature-react-global-search",
|
|
3
|
+
"version": "1.117.2",
|
|
4
|
+
"description": "Global search feature for Salesforce objects with filtering and pagination",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
|
+
"author": "",
|
|
7
|
+
"main": "src/force-app/main/default/uiBundles/feature-react-global-search/src/index.ts",
|
|
8
|
+
"types": "index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./index.d.ts",
|
|
12
|
+
"import": "./src/force-app/main/default/uiBundles/feature-react-global-search/src/index.ts",
|
|
13
|
+
"default": "./src/force-app/main/default/uiBundles/feature-react-global-search/src/index.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"clean": "rm -rf dist"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/react": "^19.2.7",
|
|
28
|
+
"@types/react-dom": "^19.2.3",
|
|
29
|
+
"@types/react-router-dom": "^5.3.3",
|
|
30
|
+
"class-variance-authority": "^0.7.1",
|
|
31
|
+
"lucide-react": "^0.468.0",
|
|
32
|
+
"react-dom": "^19.2.1",
|
|
33
|
+
"react-router": "^7.10.1",
|
|
34
|
+
"react-router-dom": "^7.10.1",
|
|
35
|
+
"zod": "^3.24.1"
|
|
36
|
+
},
|
|
37
|
+
"nx": {
|
|
38
|
+
"targets": {
|
|
39
|
+
"build": {
|
|
40
|
+
"executor": "@salesforce/ui-bundle-template-cli:apply-patches"
|
|
41
|
+
},
|
|
42
|
+
"watch": {
|
|
43
|
+
"executor": "@salesforce/ui-bundle-template-cli:watch-patches"
|
|
44
|
+
},
|
|
45
|
+
"build:dist-app": {
|
|
46
|
+
"executor": "@salesforce/ui-bundle-template-cli:build-dist-app"
|
|
47
|
+
},
|
|
48
|
+
"dev": {
|
|
49
|
+
"executor": "@salesforce/ui-bundle-template-cli:dev-server"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
+
|
|
3
|
+
const statusAlertVariants = cva("", {
|
|
4
|
+
variants: {
|
|
5
|
+
variant: {
|
|
6
|
+
error: "",
|
|
7
|
+
success: "",
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
defaultVariants: {
|
|
11
|
+
variant: "error",
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
interface StatusAlertProps extends VariantProps<typeof statusAlertVariants> {
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
/** Alert variant type. @default "error" */
|
|
18
|
+
variant?: "error" | "success";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Status alert component for displaying error or success messages.
|
|
23
|
+
* Returns null if no children are provided.
|
|
24
|
+
*/
|
|
25
|
+
export function StatusAlert({}: StatusAlertProps) {
|
|
26
|
+
return <></>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
+
|
|
3
|
+
const alertVariants = cva(
|
|
4
|
+
"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
default: "bg-card text-card-foreground",
|
|
9
|
+
destructive:
|
|
10
|
+
"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
variant: "default",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
function Alert({
|
|
20
|
+
className,
|
|
21
|
+
variant,
|
|
22
|
+
role,
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
|
|
25
|
+
return <> </>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Maintenance/A11y: Added 'asChild' pattern or a simple 'as' prop
|
|
29
|
+
// to allow rendering semantic headings (h1-h6).
|
|
30
|
+
interface AlertTitleProps extends React.ComponentProps<"div"> {
|
|
31
|
+
as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div" | "p";
|
|
32
|
+
}
|
|
33
|
+
function AlertTitle({ className, as: Component = "div", ...props }: AlertTitleProps) {
|
|
34
|
+
return <></>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
|
|
38
|
+
return <></>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { Alert, AlertTitle, AlertDescription };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
const buttonVariants = cva(
|
|
5
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
10
|
+
outline:
|
|
11
|
+
"border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
12
|
+
secondary:
|
|
13
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
14
|
+
ghost:
|
|
15
|
+
"hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
16
|
+
destructive:
|
|
17
|
+
"bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
|
|
18
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
19
|
+
},
|
|
20
|
+
size: {
|
|
21
|
+
default:
|
|
22
|
+
"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
23
|
+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
24
|
+
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
25
|
+
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
26
|
+
icon: "size-8",
|
|
27
|
+
"icon-xs":
|
|
28
|
+
"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
|
29
|
+
"icon-sm":
|
|
30
|
+
"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
|
31
|
+
"icon-lg": "size-9",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: "default",
|
|
36
|
+
size: "default",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
function Button({}: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants>) {
|
|
42
|
+
return <> </>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function Card({ className, ...props }: React.ComponentProps<"div">) {
|
|
2
|
+
return <> </>;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
6
|
+
return <> </>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function CardTitle({
|
|
10
|
+
className,
|
|
11
|
+
as: Component = "h3",
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<"div"> & { as?: any }) {
|
|
14
|
+
return <> </>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
|
|
18
|
+
return <></>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
|
|
22
|
+
return <></>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
26
|
+
return <></>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
30
|
+
return <></>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { Label } from "./__inherit__label";
|
|
4
|
+
|
|
5
|
+
function Field({
|
|
6
|
+
className,
|
|
7
|
+
orientation = "vertical",
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<"div"> & {
|
|
10
|
+
orientation?: "horizontal" | "vertical";
|
|
11
|
+
}) {
|
|
12
|
+
return <> </>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {
|
|
16
|
+
return <> </>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
20
|
+
return <> </>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function FieldError({
|
|
24
|
+
className,
|
|
25
|
+
errors,
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<"p"> & { errors?: (Error | undefined | null)[] }) {
|
|
28
|
+
const errorMessages = errors?.filter(Boolean).map((e) => e?.message);
|
|
29
|
+
|
|
30
|
+
if (!errorMessages?.length) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return <></>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
38
|
+
return <> </>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
|
42
|
+
return <> </>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function FieldLegend({ className, ...props }: React.ComponentProps<"legend">) {
|
|
46
|
+
return <> </>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function FieldSeparator({ className, ...props }: React.ComponentProps<"div">) {
|
|
50
|
+
return <></>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
Field,
|
|
55
|
+
FieldDescription,
|
|
56
|
+
FieldError,
|
|
57
|
+
FieldGroup,
|
|
58
|
+
FieldLabel,
|
|
59
|
+
FieldLegend,
|
|
60
|
+
FieldSeparator,
|
|
61
|
+
FieldSet,
|
|
62
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Button } from "./__inherit__button";
|
|
3
|
+
|
|
4
|
+
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => <></>;
|
|
5
|
+
Pagination.displayName = "Pagination";
|
|
6
|
+
|
|
7
|
+
const PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<"ul">>(
|
|
8
|
+
({ className, ...props }, ref) => <></>,
|
|
9
|
+
);
|
|
10
|
+
PaginationContent.displayName = "PaginationContent";
|
|
11
|
+
|
|
12
|
+
const PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(
|
|
13
|
+
({ className, ...props }, ref) => <></>,
|
|
14
|
+
);
|
|
15
|
+
PaginationItem.displayName = "PaginationItem";
|
|
16
|
+
|
|
17
|
+
type PaginationLinkProps = {
|
|
18
|
+
isActive?: boolean;
|
|
19
|
+
} & React.ComponentProps<"button">;
|
|
20
|
+
|
|
21
|
+
const PaginationLink = ({ className, isActive, disabled, ...props }: PaginationLinkProps) => <></>;
|
|
22
|
+
PaginationLink.displayName = "PaginationLink";
|
|
23
|
+
|
|
24
|
+
const PaginationPrevious = ({
|
|
25
|
+
className,
|
|
26
|
+
disabled,
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<typeof Button>) => <></>;
|
|
29
|
+
PaginationPrevious.displayName = "PaginationPrevious";
|
|
30
|
+
|
|
31
|
+
const PaginationNext = ({ className, disabled, ...props }: React.ComponentProps<typeof Button>) => (
|
|
32
|
+
<></>
|
|
33
|
+
);
|
|
34
|
+
PaginationNext.displayName = "PaginationNext";
|
|
35
|
+
|
|
36
|
+
const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => <></>;
|
|
37
|
+
PaginationEllipsis.displayName = "PaginationEllipsis";
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
Pagination,
|
|
41
|
+
PaginationContent,
|
|
42
|
+
PaginationEllipsis,
|
|
43
|
+
PaginationItem,
|
|
44
|
+
PaginationLink,
|
|
45
|
+
PaginationNext,
|
|
46
|
+
PaginationPrevious,
|
|
47
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Select as SelectPrimitive } from "radix-ui";
|
|
3
|
+
|
|
4
|
+
function Select({}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
5
|
+
return <></>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function SelectGroup({}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
|
9
|
+
return <></>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function SelectValue({}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
|
13
|
+
return <></>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function SelectTrigger({}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
|
17
|
+
size?: "sm" | "default";
|
|
18
|
+
}) {
|
|
19
|
+
return <></>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function SelectContent({}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
|
23
|
+
return <></>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function SelectLabel({}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
|
27
|
+
return <></>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function SelectItem({}: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
|
31
|
+
return <></>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function SelectSeparator({}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
|
35
|
+
return <></>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function SelectScrollUpButton({}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
|
39
|
+
return <></>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function SelectScrollDownButton({}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
|
43
|
+
return <></>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
Select,
|
|
48
|
+
SelectContent,
|
|
49
|
+
SelectGroup,
|
|
50
|
+
SelectItem,
|
|
51
|
+
SelectLabel,
|
|
52
|
+
SelectScrollDownButton,
|
|
53
|
+
SelectScrollUpButton,
|
|
54
|
+
SelectSeparator,
|
|
55
|
+
SelectTrigger,
|
|
56
|
+
SelectValue,
|
|
57
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record detail service: layout (REST), object metadata (GraphQL), single record (GraphQL).
|
|
3
|
+
*
|
|
4
|
+
* getRecordDetail orchestrates layout + objectInfoBatch + getRecordByIdGraphQL for the detail page.
|
|
5
|
+
* Layout is still REST (uiApiClient); record and object info are GraphQL-backed.
|
|
6
|
+
*
|
|
7
|
+
* @module api/objectDetailService
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { uiApiClient } from "@salesforce/ui-bundle/api";
|
|
11
|
+
import type { LayoutResponse } from "../types/recordDetail/recordDetail";
|
|
12
|
+
import { LayoutResponseSchema } from "../types/recordDetail/recordDetail";
|
|
13
|
+
import { fetchAndValidate, safeEncodePath } from "../utils/apiUtils";
|
|
14
|
+
import { objectInfoService } from "./objectInfoService";
|
|
15
|
+
import type { ObjectInfoResult } from "../types/objectInfo/objectInfo";
|
|
16
|
+
import { getRecordByIdGraphQL, type GraphQLRecordNode } from "./recordListGraphQLService";
|
|
17
|
+
import type { Column } from "../types/search/searchResults";
|
|
18
|
+
import { calculateFieldsToFetch } from "../utils/recordUtils";
|
|
19
|
+
|
|
20
|
+
/** Fallback when record type is unknown. Prefer recordTypeId from the record (e.g. from search or record response) when available. */
|
|
21
|
+
const DEFAULT_RECORD_TYPE_ID = "012000000000000AAA";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns field API names to request for a record from the given layout and object metadata.
|
|
25
|
+
* Used to derive GraphQL columns from layout (detail view). Delegates to recordUtils.calculateFieldsToFetch.
|
|
26
|
+
*
|
|
27
|
+
* @param objectMetadata - Object info (fields, relationshipName, etc.).
|
|
28
|
+
* @param layout - Layout response (sections, layoutItems, layoutComponents).
|
|
29
|
+
* @returns Array of field API names (e.g. ["Name", "OwnerId", "Owner", "CreatedDate"]).
|
|
30
|
+
*/
|
|
31
|
+
export function extractFieldsFromLayout(
|
|
32
|
+
objectMetadata: ObjectInfoResult,
|
|
33
|
+
layout: LayoutResponse,
|
|
34
|
+
): string[] {
|
|
35
|
+
const [optionalFields] = calculateFieldsToFetch(objectMetadata, layout, false);
|
|
36
|
+
return optionalFields;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function getLayout(
|
|
40
|
+
objectApiName: string,
|
|
41
|
+
recordTypeId: string = DEFAULT_RECORD_TYPE_ID,
|
|
42
|
+
): Promise<LayoutResponse> {
|
|
43
|
+
const params = new URLSearchParams({
|
|
44
|
+
layoutType: "Full",
|
|
45
|
+
mode: "View",
|
|
46
|
+
recordTypeId,
|
|
47
|
+
});
|
|
48
|
+
return fetchAndValidate(
|
|
49
|
+
() => uiApiClient.get(`/layout/${safeEncodePath(objectApiName)}?${params.toString()}`),
|
|
50
|
+
{
|
|
51
|
+
schema: LayoutResponseSchema,
|
|
52
|
+
errorContext: `layout for ${objectApiName}`,
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface RecordDetailResult {
|
|
58
|
+
layout: LayoutResponse;
|
|
59
|
+
record: GraphQLRecordNode;
|
|
60
|
+
objectMetadata: ObjectInfoResult;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Converts layout-derived optionalFields (field API names) to Column[] for GraphQL node selection.
|
|
65
|
+
* Uses unqualified names (no entity prefix) so the GraphQL query matches UI API shape.
|
|
66
|
+
* Other Column fields (label, searchable, sortable) are only required by the type; GraphQL selection uses fieldApiName only.
|
|
67
|
+
*/
|
|
68
|
+
function optionalFieldsToColumns(optionalFields: string[]): Column[] {
|
|
69
|
+
return optionalFields.map((fieldApiName) => ({
|
|
70
|
+
fieldApiName,
|
|
71
|
+
label: "",
|
|
72
|
+
searchable: false,
|
|
73
|
+
sortable: false,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function getRecordDetail(
|
|
78
|
+
objectApiName: string,
|
|
79
|
+
recordId: string,
|
|
80
|
+
recordTypeId: string = DEFAULT_RECORD_TYPE_ID,
|
|
81
|
+
): Promise<RecordDetailResult> {
|
|
82
|
+
const layout = await getLayout(objectApiName, recordTypeId);
|
|
83
|
+
const objectMetadata = await objectInfoService.getObjectInfoBatch(objectApiName);
|
|
84
|
+
const firstResult = objectMetadata?.results?.[0]?.result;
|
|
85
|
+
if (!firstResult) {
|
|
86
|
+
throw new Error(`Object metadata not found for ${objectApiName}`);
|
|
87
|
+
}
|
|
88
|
+
// Layout-driven optionalFields (fields shown on the detail layout), not list columns
|
|
89
|
+
const [optionalFields] = calculateFieldsToFetch(firstResult, layout, false);
|
|
90
|
+
const columns = optionalFieldsToColumns(optionalFields);
|
|
91
|
+
const record = await getRecordByIdGraphQL(objectApiName, recordId, columns);
|
|
92
|
+
if (!record) {
|
|
93
|
+
throw new Error(`Record not found: ${recordId}`);
|
|
94
|
+
}
|
|
95
|
+
return { layout, record, objectMetadata: firstResult };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const objectDetailService = {
|
|
99
|
+
extractFieldsFromLayout,
|
|
100
|
+
getLayout,
|
|
101
|
+
getRecordDetail,
|
|
102
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object metadata GraphQL service (uiapi.objectInfos).
|
|
3
|
+
*
|
|
4
|
+
* Single endpoint for object describe and picklist values. Used by objectInfoService
|
|
5
|
+
* to implement getObjectInfoBatch and getPicklistValues. Not used directly by UI.
|
|
6
|
+
*
|
|
7
|
+
* @module api/objectInfoGraphQLService
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createDataSDK, gql } from "@salesforce/sdk-data";
|
|
11
|
+
import type {
|
|
12
|
+
GetObjectInfosQuery,
|
|
13
|
+
GetObjectInfosQueryVariables,
|
|
14
|
+
GetPicklistValuesQuery,
|
|
15
|
+
GetPicklistValuesQueryVariables,
|
|
16
|
+
ObjectInfoInput,
|
|
17
|
+
} from "../types/schema";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Builds objectInfos query (metadata only). Uses apiNames only — do not pass objectInfoInputs.
|
|
21
|
+
*/
|
|
22
|
+
const OBJECT_INFOS_QUERY = gql`
|
|
23
|
+
query GetObjectInfos($apiNames: [String!]!) {
|
|
24
|
+
uiapi {
|
|
25
|
+
objectInfos(apiNames: $apiNames) {
|
|
26
|
+
ApiName
|
|
27
|
+
label
|
|
28
|
+
labelPlural
|
|
29
|
+
nameFields
|
|
30
|
+
defaultRecordTypeId
|
|
31
|
+
keyPrefix
|
|
32
|
+
layoutable
|
|
33
|
+
queryable
|
|
34
|
+
searchable
|
|
35
|
+
updateable
|
|
36
|
+
deletable
|
|
37
|
+
createable
|
|
38
|
+
custom
|
|
39
|
+
mruEnabled
|
|
40
|
+
feedEnabled
|
|
41
|
+
fields {
|
|
42
|
+
ApiName
|
|
43
|
+
label
|
|
44
|
+
dataType
|
|
45
|
+
relationshipName
|
|
46
|
+
reference
|
|
47
|
+
compound
|
|
48
|
+
compoundFieldName
|
|
49
|
+
compoundComponentName
|
|
50
|
+
controllingFields
|
|
51
|
+
controllerName
|
|
52
|
+
referenceToInfos {
|
|
53
|
+
ApiName
|
|
54
|
+
nameFields
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
recordTypeInfos {
|
|
58
|
+
recordTypeId
|
|
59
|
+
name
|
|
60
|
+
master
|
|
61
|
+
available
|
|
62
|
+
defaultRecordTypeMapping
|
|
63
|
+
}
|
|
64
|
+
themeInfo {
|
|
65
|
+
color
|
|
66
|
+
iconUrl
|
|
67
|
+
}
|
|
68
|
+
childRelationships {
|
|
69
|
+
relationshipName
|
|
70
|
+
fieldName
|
|
71
|
+
childObjectApiName
|
|
72
|
+
}
|
|
73
|
+
dependentFields {
|
|
74
|
+
controllingField
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Builds objectInfos query with picklist values (API v65.0+).
|
|
83
|
+
* Schema requires objectInfos to be called with either apiNames or objectInfoInputs, not both.
|
|
84
|
+
* This query uses objectInfoInputs only.
|
|
85
|
+
* Optimized to only fetch fields used by extractPicklistValuesFromGraphQLObjectInfo.
|
|
86
|
+
*/
|
|
87
|
+
const PICKLIST_VALUES_QUERY = gql`
|
|
88
|
+
query GetPicklistValues($objectInfoInputs: [ObjectInfoInput!]!) {
|
|
89
|
+
uiapi {
|
|
90
|
+
objectInfos(objectInfoInputs: $objectInfoInputs) {
|
|
91
|
+
ApiName
|
|
92
|
+
fields {
|
|
93
|
+
ApiName
|
|
94
|
+
... on PicklistField {
|
|
95
|
+
picklistValuesByRecordTypeIDs {
|
|
96
|
+
recordTypeID
|
|
97
|
+
defaultValue {
|
|
98
|
+
value
|
|
99
|
+
}
|
|
100
|
+
picklistValues {
|
|
101
|
+
label
|
|
102
|
+
value
|
|
103
|
+
validFor
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
export async function queryForObjectInfos(apiNames: string[]): Promise<GetObjectInfosQuery> {
|
|
114
|
+
return runQuery<GetObjectInfosQuery, GetObjectInfosQueryVariables>(OBJECT_INFOS_QUERY, {
|
|
115
|
+
apiNames,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function queryForPicklistValues(
|
|
120
|
+
objectInfoInputs: ObjectInfoInput[],
|
|
121
|
+
): Promise<GetPicklistValuesQuery> {
|
|
122
|
+
return runQuery<GetPicklistValuesQuery, GetPicklistValuesQueryVariables>(PICKLIST_VALUES_QUERY, {
|
|
123
|
+
objectInfoInputs,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function runQuery<Q, V>(query: string, variables: V): Promise<Q> {
|
|
128
|
+
const data = await createDataSDK();
|
|
129
|
+
const response = await data.graphql?.<Q, V>(query, variables);
|
|
130
|
+
|
|
131
|
+
if (response?.errors?.length) {
|
|
132
|
+
const errorMessages = response.errors.map((e) => e.message).join("; ");
|
|
133
|
+
throw new Error(`GraphQL Error: ${errorMessages}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return response?.data ?? ({} as Q);
|
|
137
|
+
}
|