@salesforce/templates 66.13.5 → 66.13.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/templates/project/angularextapp/CHANGELOG.md +258 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +1 -1
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +299 -279
- package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +2 -2
- package/lib/templates/project/angularextapp/package.json +1 -1
- package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +17 -0
- package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +33 -3
- package/lib/templates/project/angularextapp/scripts/org-setup.mjs +535 -3
- package/lib/templates/project/angularintapp/CHANGELOG.md +266 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +1 -1
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +309 -289
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +2 -2
- package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +6 -1
- package/lib/templates/project/angularintapp/package.json +1 -1
- package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +17 -0
- package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +33 -3
- package/lib/templates/project/angularintapp/scripts/org-setup.mjs +535 -3
- package/lib/templates/project/reactexternalapp/CHANGELOG.md +1313 -0
- package/lib/templates/project/reactexternalapp/PRD.md +38 -0
- package/lib/templates/project/reactexternalapp/README.md +14 -10
- package/lib/templates/project/reactexternalapp/_p_/_m_/_ps_/reactexternalapp_Guest_User_Api_Access.permissionset-meta.xml +25 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +587 -626
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +9 -7
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +8 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/components/SocialLogin.tsx +141 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Login.tsx +2 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +71 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +277 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +185 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +77 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +182 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +55 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
- package/lib/templates/project/{reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters → reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs}/FilterFieldWrapper.tsx +11 -6
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +83 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +703 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +90 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +156 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +307 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphqlClient.ts +24 -8
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/appLayout.tsx +7 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/CustomerWebClientChat.tsx +74 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/index.ts +6 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +49 -16
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +21 -293
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +22 -7
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/TestChatPage.tsx +26 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +11 -5
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/types/chat.ts +36 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls +133 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls-meta.xml +5 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls +101 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls-meta.xml +5 -0
- package/lib/templates/project/reactexternalapp/_p_/_m_/package.xml +4 -0
- package/lib/templates/project/reactexternalapp/package.json +8 -2
- package/lib/templates/project/reactexternalapp/scripts/org-setup-config-schema.mjs +120 -0
- package/lib/templates/project/reactexternalapp/scripts/org-setup-dev.mjs +87 -0
- package/lib/templates/project/reactexternalapp/scripts/org-setup-utils.mjs +569 -0
- package/lib/templates/project/reactexternalapp/scripts/org-setup-xml.mjs +182 -0
- package/lib/templates/project/reactexternalapp/scripts/org-setup.config.json +6 -2
- package/lib/templates/project/reactexternalapp/scripts/org-setup.mjs +1509 -328
- package/lib/templates/project/reactexternalapp/scripts/validate-org-setup-config.mjs +38 -0
- package/lib/templates/project/reactinternalapp/CHANGELOG.md +1127 -0
- package/lib/templates/project/reactinternalapp/PRD.md +35 -0
- package/lib/templates/project/reactinternalapp/README.md +14 -10
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +436 -439
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package.json +9 -8
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +71 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +277 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +185 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +77 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +182 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +55 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
- package/lib/templates/project/{reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters → reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs}/FilterFieldWrapper.tsx +11 -6
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +83 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +703 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +90 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +156 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +307 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.tsx +16 -132
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +49 -16
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +21 -293
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +21 -6
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +4 -4
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
- package/lib/templates/project/reactinternalapp/package.json +4 -2
- package/lib/templates/project/reactinternalapp/scripts/org-setup-config-schema.mjs +24 -0
- package/lib/templates/project/reactinternalapp/scripts/org-setup-dev.mjs +87 -0
- package/lib/templates/project/reactinternalapp/scripts/org-setup-utils.mjs +569 -0
- package/lib/templates/project/reactinternalapp/scripts/org-setup-xml.mjs +182 -0
- package/lib/templates/project/reactinternalapp/scripts/org-setup.mjs +1162 -214
- package/lib/templates/uiBundles/angularbasic/angular.json +1 -1
- package/lib/templates/uiBundles/angularbasic/eslint-plugin-angular-graphql.js +148 -0
- package/lib/templates/uiBundles/angularbasic/eslint.config.js +9 -1
- package/lib/templates/uiBundles/angularbasic/package-lock.json +299 -279
- package/lib/templates/uiBundles/angularbasic/package.json +2 -2
- package/lib/templates/uiBundles/reactbasic/package-lock.json +372 -352
- package/lib/utils/template-placeholders.js +7 -0
- package/lib/utils/template-placeholders.js.map +1 -1
- package/lib/utils/uiBundleTemplateUtils.d.ts +3 -1
- package/lib/utils/uiBundleTemplateUtils.js +4 -1
- package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
- package/package.json +7 -7
- package/lib/templates/project/reactexternalapp/AGENT.md +0 -252
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
- package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
- package/lib/templates/project/reactexternalapp/scripts/prepare-import-unique-fields.js +0 -122
- package/lib/templates/project/reactinternalapp/AGENT.md +0 -252
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
- package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
- package/lib/templates/project/reactinternalapp/scripts/prepare-import-unique-fields.js +0 -122
- /package/lib/templates/project/angularextapp/_p_/_m_/{permissionsets → _ps_}/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +0 -0
- /package/lib/templates/project/angularintapp/_p_/_m_/{permissionsets → _ps_}/angularintapp_Access.permissionset-meta.xml +0 -0
- /package/lib/templates/project/reactinternalapp/_p_/_m_/{permissionsets → _ps_}/reactinternalapp_Access.permissionset-meta.xml +0 -0
|
@@ -1,297 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Collapsible,
|
|
17
|
-
CollapsibleContent,
|
|
18
|
-
CollapsibleTrigger,
|
|
19
|
-
} from "../components/ui/collapsible";
|
|
20
|
-
import { Skeleton } from "../components/ui/skeleton";
|
|
21
|
-
import {
|
|
22
|
-
FilterProvider,
|
|
23
|
-
FilterResetButton,
|
|
24
|
-
} from "../features/object-search/components/FilterContext";
|
|
25
|
-
import { SearchFilter } from "../features/object-search/components/filters/SearchFilter";
|
|
26
|
-
import { TextFilter } from "../features/object-search/components/filters/TextFilter";
|
|
27
|
-
import { SelectFilter } from "../features/object-search/components/filters/SelectFilter";
|
|
28
|
-
import { MultiSelectFilter } from "../features/object-search/components/filters/MultiSelectFilter";
|
|
29
|
-
import { NumericRangeFilter } from "../features/object-search/components/filters/NumericRangeFilter";
|
|
30
|
-
import { DateFilter } from "../features/object-search/components/filters/DateFilter";
|
|
31
|
-
import { DateRangeFilter } from "../features/object-search/components/filters/DateRangeFilter";
|
|
32
|
-
import { ActiveFilters } from "../features/object-search/components/ActiveFilters";
|
|
33
|
-
import { SortControl } from "../features/object-search/components/SortControl";
|
|
34
|
-
import type { FilterFieldConfig } from "../features/object-search/utils/filterUtils";
|
|
35
|
-
import type { SortFieldConfig } from "../features/object-search/utils/sortUtils";
|
|
36
|
-
import type { Account_Filter, Account_OrderBy } from "../api/graphql-operations-types";
|
|
37
|
-
import type { AccountSearchResult } from "../api/account/accountSearchService";
|
|
38
|
-
import { ObjectBreadcrumb } from "../features/object-search/components/ObjectBreadcrumb";
|
|
39
|
-
import PaginationControls from "../features/object-search/components/PaginationControls";
|
|
40
|
-
import type { PaginationConfig } from "../features/object-search/hooks/useObjectSearchParams";
|
|
41
|
-
|
|
42
|
-
const PAGINATION_CONFIG: PaginationConfig = {
|
|
43
|
-
defaultPageSize: 7,
|
|
44
|
-
validPageSizes: [7, 14, 28, 42],
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
type AccountNode = NonNullable<
|
|
48
|
-
NonNullable<NonNullable<AccountSearchResult["edges"]>[number]>["node"]
|
|
49
|
-
>;
|
|
50
|
-
|
|
51
|
-
const FILTER_CONFIGS: FilterFieldConfig[] = [
|
|
52
|
-
{
|
|
53
|
-
field: "search",
|
|
54
|
-
label: "Search",
|
|
55
|
-
type: "search",
|
|
56
|
-
searchFields: ["Name", "Phone", "Industry"],
|
|
57
|
-
placeholder: "Search by name, phone, or industry...",
|
|
58
|
-
},
|
|
59
|
-
{ field: "Name", label: "Account Name", type: "text", placeholder: "Search by name..." },
|
|
60
|
-
{ field: "Industry", label: "Industry", type: "picklist" },
|
|
61
|
-
{ field: "Type", label: "Type", type: "multipicklist" },
|
|
62
|
-
{ field: "AnnualRevenue", label: "Annual Revenue", type: "numeric" },
|
|
63
|
-
{ field: "CreatedDate", label: "Created Date", type: "datetime" },
|
|
64
|
-
{ field: "LastModifiedDate", label: "Last Modified Date", type: "datetimerange" },
|
|
65
|
-
];
|
|
66
|
-
|
|
67
|
-
const ACCOUNT_SORT_CONFIGS: SortFieldConfig<keyof Account_OrderBy>[] = [
|
|
68
|
-
{ field: "Name", label: "Name" },
|
|
69
|
-
{ field: "AnnualRevenue", label: "Annual Revenue" },
|
|
70
|
-
{ field: "Industry", label: "Industry" },
|
|
71
|
-
{ field: "CreatedDate", label: "Created Date" },
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
// -- Component --------------------------------------------------------------
|
|
75
|
-
|
|
1
|
+
import { Search, config } from "../features/search";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Account search page.
|
|
5
|
+
*
|
|
6
|
+
* Renders the config-driven `<Search>` feature (feature-react-search) locked to
|
|
7
|
+
* the Account source via `restrictTo`. The shared `config.json` already defines
|
|
8
|
+
* the Account source's searchable fields, filters, sort options, and
|
|
9
|
+
* `routePattern` ("/accounts/:id"), so result rows link to the Account detail
|
|
10
|
+
* page and the filter / sort chrome render automatically — no per-page wiring.
|
|
11
|
+
*
|
|
12
|
+
* `restrictTo` hides the scope selector and fetches only Accounts, so the page
|
|
13
|
+
* reads as a single-object search even though the underlying feature supports
|
|
14
|
+
* many sources.
|
|
15
|
+
*/
|
|
76
16
|
export default function AccountSearch() {
|
|
77
|
-
const [filtersOpen, setFiltersOpen] = useState(true);
|
|
78
|
-
const { data: industryOptions } = useAsyncData(fetchDistinctIndustries, []);
|
|
79
|
-
const { data: typeOptions } = useAsyncData(fetchDistinctTypes, []);
|
|
80
|
-
|
|
81
|
-
const { filters, sort, query, pagination, resetAll } = useObjectSearchParams<
|
|
82
|
-
Account_Filter,
|
|
83
|
-
Account_OrderBy
|
|
84
|
-
>(FILTER_CONFIGS, ACCOUNT_SORT_CONFIGS, PAGINATION_CONFIG);
|
|
85
|
-
|
|
86
|
-
const { data, loading, error } = useAsyncData(
|
|
87
|
-
() =>
|
|
88
|
-
searchAccounts({
|
|
89
|
-
where: query.where,
|
|
90
|
-
orderBy: query.orderBy,
|
|
91
|
-
first: pagination.pageSize,
|
|
92
|
-
after: pagination.afterCursor,
|
|
93
|
-
}),
|
|
94
|
-
[query.where, query.orderBy, pagination.pageSize, pagination.afterCursor],
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
const pageInfo = data?.pageInfo;
|
|
98
|
-
const totalCount = data?.totalCount;
|
|
99
|
-
const hasNextPage = pageInfo?.hasNextPage ?? false;
|
|
100
|
-
const hasPreviousPage = pagination.pageIndex > 0;
|
|
101
|
-
|
|
102
|
-
const validAccountNodes = useMemo(
|
|
103
|
-
() =>
|
|
104
|
-
(data?.edges ?? []).reduce<AccountNode[]>((acc, edge) => {
|
|
105
|
-
if (edge?.node) acc.push(edge.node);
|
|
106
|
-
return acc;
|
|
107
|
-
}, []),
|
|
108
|
-
[data?.edges],
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
113
|
-
<ObjectBreadcrumb listPath="/accounts" listLabel="Accounts" />
|
|
114
|
-
|
|
115
|
-
<h1 className="text-2xl font-bold mb-4">Search Accounts</h1>
|
|
116
|
-
|
|
117
|
-
<div className="flex flex-col lg:flex-row gap-6">
|
|
118
|
-
{/* Sidebar — Filter Panel */}
|
|
119
|
-
<aside className="w-full lg:w-80 shrink-0">
|
|
120
|
-
<FilterProvider
|
|
121
|
-
filters={filters.active}
|
|
122
|
-
onFilterChange={filters.set}
|
|
123
|
-
onFilterRemove={filters.remove}
|
|
124
|
-
onReset={resetAll}
|
|
125
|
-
>
|
|
126
|
-
<Card>
|
|
127
|
-
<Collapsible open={filtersOpen} onOpenChange={setFiltersOpen}>
|
|
128
|
-
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
|
129
|
-
<CardTitle className="text-base font-semibold">
|
|
130
|
-
<h2>Filters</h2>
|
|
131
|
-
</CardTitle>
|
|
132
|
-
<div className="flex items-center gap-1">
|
|
133
|
-
<FilterResetButton variant="destructive" size="sm" />
|
|
134
|
-
<CollapsibleTrigger asChild>
|
|
135
|
-
<Button variant="ghost" size="icon">
|
|
136
|
-
<ChevronDown
|
|
137
|
-
className={`h-4 w-4 transition-transform ${filtersOpen ? "" : "-rotate-90"}`}
|
|
138
|
-
/>
|
|
139
|
-
<span className="sr-only">Toggle filters</span>
|
|
140
|
-
</Button>
|
|
141
|
-
</CollapsibleTrigger>
|
|
142
|
-
</div>
|
|
143
|
-
</CardHeader>
|
|
144
|
-
<CollapsibleContent>
|
|
145
|
-
<CardContent className="space-y-1 pt-0">
|
|
146
|
-
<SearchFilter
|
|
147
|
-
field="search"
|
|
148
|
-
label="Search"
|
|
149
|
-
placeholder="Search by name, phone, or industry..."
|
|
150
|
-
/>
|
|
151
|
-
<TextFilter field="Name" label="Account Name" placeholder="Search by name..." />
|
|
152
|
-
<SelectFilter
|
|
153
|
-
field="Industry"
|
|
154
|
-
label="Industry"
|
|
155
|
-
options={industryOptions ?? []}
|
|
156
|
-
/>
|
|
157
|
-
<MultiSelectFilter field="Type" label="Type" options={typeOptions ?? []} />
|
|
158
|
-
<NumericRangeFilter field="AnnualRevenue" label="Annual Revenue" />
|
|
159
|
-
<DateFilter field="CreatedDate" label="Created Date" filterType="datetime" />
|
|
160
|
-
<DateRangeFilter
|
|
161
|
-
field="LastModifiedDate"
|
|
162
|
-
label="Last Modified Date"
|
|
163
|
-
filterType="datetimerange"
|
|
164
|
-
/>
|
|
165
|
-
</CardContent>
|
|
166
|
-
</CollapsibleContent>
|
|
167
|
-
</Collapsible>
|
|
168
|
-
</Card>
|
|
169
|
-
</FilterProvider>
|
|
170
|
-
</aside>
|
|
171
|
-
|
|
172
|
-
{/* Main area — Sort + Results */}
|
|
173
|
-
<div className="flex-1 min-w-0">
|
|
174
|
-
{/* Sort control + active filters */}
|
|
175
|
-
<div className="flex flex-wrap items-center gap-2 mb-4">
|
|
176
|
-
<SortControl
|
|
177
|
-
configs={ACCOUNT_SORT_CONFIGS}
|
|
178
|
-
sort={sort.current}
|
|
179
|
-
onSortChange={sort.set}
|
|
180
|
-
/>
|
|
181
|
-
<ActiveFilters filters={filters.active} onRemove={filters.remove} />
|
|
182
|
-
</div>
|
|
183
|
-
|
|
184
|
-
<div className="min-h-132">
|
|
185
|
-
{/* Loading state */}
|
|
186
|
-
{loading && (
|
|
187
|
-
<>
|
|
188
|
-
<Skeleton className="h-5 w-30 mb-3" />
|
|
189
|
-
<div className="divide-y">
|
|
190
|
-
{Array.from({ length: pagination.pageSize }, (_, i) => (
|
|
191
|
-
<div key={i} className="flex items-center justify-between py-3">
|
|
192
|
-
<div className="space-y-2">
|
|
193
|
-
<Skeleton className="h-5 w-40" />
|
|
194
|
-
<Skeleton className="h-4 w-28" />
|
|
195
|
-
</div>
|
|
196
|
-
<div className="space-y-2 flex flex-col items-end">
|
|
197
|
-
<Skeleton className="h-4 w-24" />
|
|
198
|
-
<Skeleton className="h-4 w-20" />
|
|
199
|
-
</div>
|
|
200
|
-
</div>
|
|
201
|
-
))}
|
|
202
|
-
</div>
|
|
203
|
-
</>
|
|
204
|
-
)}
|
|
205
|
-
|
|
206
|
-
{/* Error state */}
|
|
207
|
-
{error && (
|
|
208
|
-
<>
|
|
209
|
-
<p className="text-sm text-muted-foreground mb-3">0 accounts found</p>
|
|
210
|
-
<Alert variant="destructive" role="alert">
|
|
211
|
-
<AlertCircle />
|
|
212
|
-
<AlertTitle>Failed to load accounts</AlertTitle>
|
|
213
|
-
<AlertDescription>
|
|
214
|
-
Something went wrong while loading accounts. Please try again later.
|
|
215
|
-
</AlertDescription>
|
|
216
|
-
</Alert>
|
|
217
|
-
</>
|
|
218
|
-
)}
|
|
219
|
-
|
|
220
|
-
{/* Results list */}
|
|
221
|
-
{!loading && !error && validAccountNodes.length > 0 && (
|
|
222
|
-
<>
|
|
223
|
-
<p className="text-sm text-muted-foreground mb-3">
|
|
224
|
-
{totalCount != null && (hasNextPage || hasPreviousPage)
|
|
225
|
-
? `${totalCount} account${totalCount !== 1 ? "s" : ""} found`
|
|
226
|
-
: `Showing ${validAccountNodes.length} account${validAccountNodes.length !== 1 ? "s" : ""}`}
|
|
227
|
-
</p>
|
|
228
|
-
<AccountResultsList nodes={validAccountNodes} />
|
|
229
|
-
</>
|
|
230
|
-
)}
|
|
231
|
-
|
|
232
|
-
{/* No results state */}
|
|
233
|
-
{!loading && !error && validAccountNodes.length === 0 && (
|
|
234
|
-
<div className="flex flex-col items-center justify-center py-16 text-center">
|
|
235
|
-
<SearchX className="size-12 text-muted-foreground mb-4" />
|
|
236
|
-
<h2 className="text-lg font-semibold mb-1">No accounts found</h2>
|
|
237
|
-
<p className="text-sm text-muted-foreground">
|
|
238
|
-
Try adjusting your filters or search criteria.
|
|
239
|
-
</p>
|
|
240
|
-
</div>
|
|
241
|
-
)}
|
|
242
|
-
</div>
|
|
243
|
-
|
|
244
|
-
{/* Pagination — always visible, disabled while loading or on error */}
|
|
245
|
-
<PaginationControls
|
|
246
|
-
pageIndex={pagination.pageIndex}
|
|
247
|
-
hasNextPage={hasNextPage}
|
|
248
|
-
hasPreviousPage={hasPreviousPage}
|
|
249
|
-
pageSize={pagination.pageSize}
|
|
250
|
-
pageSizeOptions={PAGINATION_CONFIG.validPageSizes}
|
|
251
|
-
onNextPage={() => {
|
|
252
|
-
if (pageInfo?.endCursor) pagination.goToNextPage(pageInfo.endCursor);
|
|
253
|
-
}}
|
|
254
|
-
onPreviousPage={pagination.goToPreviousPage}
|
|
255
|
-
onPageSizeChange={pagination.setPageSize}
|
|
256
|
-
disabled={loading || !!error}
|
|
257
|
-
/>
|
|
258
|
-
</div>
|
|
259
|
-
</div>
|
|
260
|
-
</div>
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// -- Result Components ------------------------------------------------------
|
|
265
|
-
|
|
266
|
-
function AccountResultsList({ nodes }: { nodes: AccountNode[] }) {
|
|
267
|
-
return (
|
|
268
|
-
<ul className="divide-y">
|
|
269
|
-
{nodes.map((node) => (
|
|
270
|
-
<AccountResultItem key={node.Id} node={node} />
|
|
271
|
-
))}
|
|
272
|
-
</ul>
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function AccountResultItem({ node }: { node: AccountNode }) {
|
|
277
17
|
return (
|
|
278
|
-
<
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
<span className="font-medium">{fieldValue(node.Name) ?? "\u2014"}</span>
|
|
285
|
-
<p className="text-sm text-muted-foreground">
|
|
286
|
-
{[fieldValue(node.Industry), fieldValue(node.Type)].filter(Boolean).join(" \u00B7 ") ||
|
|
287
|
-
"\u2014"}
|
|
288
|
-
</p>
|
|
289
|
-
</div>
|
|
290
|
-
<div className="text-right text-sm">
|
|
291
|
-
<p>{fieldValue(node.Phone) ?? ""}</p>
|
|
292
|
-
<p className="text-muted-foreground">{fieldValue(node.Owner?.Name) ?? ""}</p>
|
|
293
|
-
</div>
|
|
294
|
-
</Link>
|
|
295
|
-
</li>
|
|
18
|
+
<Search
|
|
19
|
+
config={config}
|
|
20
|
+
title="Search Accounts"
|
|
21
|
+
searchPlaceholder="Search by name, phone, or industry..."
|
|
22
|
+
restrictTo={{ kind: "sobject", key: "accounts" }}
|
|
23
|
+
/>
|
|
296
24
|
);
|
|
297
25
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import { useNavigate } from "react-router";
|
|
3
|
-
import {
|
|
3
|
+
import { Search } from "lucide-react";
|
|
4
|
+
import { Input } from "../components/ui/input";
|
|
4
5
|
import { Button } from "../components/ui/button";
|
|
5
6
|
|
|
6
7
|
export default function HomePage() {
|
|
@@ -9,6 +10,8 @@ export default function HomePage() {
|
|
|
9
10
|
|
|
10
11
|
const handleSubmit = (e: React.SyntheticEvent<HTMLFormElement>) => {
|
|
11
12
|
e.preventDefault();
|
|
13
|
+
// `q` matches the search feature's GLOBAL_QUERY_KEY, so the term
|
|
14
|
+
// pre-fills the Account search page on arrival.
|
|
12
15
|
const params = text ? `?q=${encodeURIComponent(text)}` : "";
|
|
13
16
|
navigate(`/accounts${params}`);
|
|
14
17
|
};
|
|
@@ -22,11 +25,23 @@ export default function HomePage() {
|
|
|
22
25
|
</Button>
|
|
23
26
|
</div>
|
|
24
27
|
<form onSubmit={handleSubmit} className="flex gap-2">
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
<div className="relative flex-1">
|
|
29
|
+
<label htmlFor="account-search-input" className="sr-only">
|
|
30
|
+
Search accounts
|
|
31
|
+
</label>
|
|
32
|
+
<Search
|
|
33
|
+
aria-hidden="true"
|
|
34
|
+
className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"
|
|
35
|
+
/>
|
|
36
|
+
<Input
|
|
37
|
+
id="account-search-input"
|
|
38
|
+
type="text"
|
|
39
|
+
value={text}
|
|
40
|
+
onChange={(e) => setText(e.target.value)}
|
|
41
|
+
placeholder="Search by name, phone, or industry..."
|
|
42
|
+
className="pl-9"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
30
45
|
<Button type="submit">Search</Button>
|
|
31
46
|
</form>
|
|
32
47
|
</div>
|
|
@@ -15,10 +15,6 @@ export const routes: RouteObject[] = [
|
|
|
15
15
|
element: <Home />,
|
|
16
16
|
handle: { showInNavigation: true, label: "Home" }
|
|
17
17
|
},
|
|
18
|
-
{
|
|
19
|
-
path: '*',
|
|
20
|
-
element: <NotFound />
|
|
21
|
-
},
|
|
22
18
|
{
|
|
23
19
|
path: "accounts/:recordId",
|
|
24
20
|
element: <AccountObjectDetail />
|
|
@@ -26,6 +22,10 @@ export const routes: RouteObject[] = [
|
|
|
26
22
|
{
|
|
27
23
|
path: "accounts",
|
|
28
24
|
element: <AccountSearch />
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: '*',
|
|
28
|
+
element: <NotFound />
|
|
29
29
|
}
|
|
30
30
|
]
|
|
31
31
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field helpers for reading uiapi GraphQL response nodes on the Account
|
|
3
|
+
* detail page. Previously imported from feature-react-object-search; inlined
|
|
4
|
+
* here so the app no longer depends on that feature.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Picks the user-facing string for a `{ value, displayValue }` field. */
|
|
1
8
|
export function fieldValue(
|
|
2
9
|
field: { displayValue?: string | null; value?: unknown } | null | undefined,
|
|
3
10
|
): string | null {
|
|
@@ -6,6 +13,7 @@ export function fieldValue(
|
|
|
6
13
|
return null;
|
|
7
14
|
}
|
|
8
15
|
|
|
16
|
+
/** Builds the display lines for a Salesforce compound address, or null if empty. */
|
|
9
17
|
export function getAddressFieldLines(address: {
|
|
10
18
|
street?: string | null;
|
|
11
19
|
city?: string | null;
|
|
@@ -20,6 +28,7 @@ export function getAddressFieldLines(address: {
|
|
|
20
28
|
return lines;
|
|
21
29
|
}
|
|
22
30
|
|
|
31
|
+
/** Formats an ISO datetime string with `toLocaleString`, or null if absent. */
|
|
23
32
|
export function formatDateTimeField(
|
|
24
33
|
value?: string | null,
|
|
25
34
|
...args: Parameters<Date["toLocaleString"]>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/app.tsx","./src/appLayout.tsx","./src/index.ts","./src/navigationMenu.tsx","./src/router-utils.tsx","./src/routes.tsx","./src/api/graphqlClient.ts","./src/components/AgentforceConversationClient.tsx","./src/components/ObjectBreadcrumb.tsx","./src/components/__inherit_AgentforceConversationClient.tsx","./src/components/alerts/status-alert.tsx","./src/components/layouts/card-layout.tsx","./src/components/ui/alert.tsx","./src/components/ui/avatar.tsx","./src/components/ui/badge.tsx","./src/components/ui/breadcrumb.tsx","./src/components/ui/button.tsx","./src/components/ui/calendar.tsx","./src/components/ui/card.tsx","./src/components/ui/checkbox.tsx","./src/components/ui/collapsible.tsx","./src/components/ui/datePicker.tsx","./src/components/ui/dialog.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/field.tsx","./src/components/ui/index.ts","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/pagination.tsx","./src/components/ui/popover.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/skeleton.tsx","./src/components/ui/sonner.tsx","./src/components/ui/spinner.tsx","./src/components/ui/table.tsx","./src/components/ui/tabs.tsx","./src/features/search/index.ts","./src/features/search/loadConfig.ts","./src/features/search/queryBuilder.ts","./src/features/search/types.ts","./src/features/search/api/distinctValuesService.ts","./src/features/search/api/searchService.ts","./src/features/search/components/MergedSearchResults.tsx","./src/features/search/components/Search.tsx","./src/features/search/components/SearchResults.tsx","./src/features/search/components/SourceSection.tsx","./src/features/search/components/controls/PaginationControls.tsx","./src/features/search/components/controls/ScopeSelector.tsx","./src/features/search/components/controls/SearchBar.tsx","./src/features/search/components/controls/SortControl.tsx","./src/features/search/components/filters/ActiveFilters.tsx","./src/features/search/components/filters/DefaultFilterPanel.tsx","./src/features/search/components/filters/FilterContext.tsx","./src/features/search/components/filters/inputs/BooleanFilter.tsx","./src/features/search/components/filters/inputs/DateRangeFilter.tsx","./src/features/search/components/filters/inputs/FilterFieldWrapper.tsx","./src/features/search/components/filters/inputs/MultiSelectFilter.tsx","./src/features/search/components/filters/inputs/NumericRangeFilter.tsx","./src/features/search/components/filters/inputs/SelectFilter.tsx","./src/features/search/components/filters/inputs/TextFilter.tsx","./src/features/search/components/results/DefaultResultRow.tsx","./src/features/search/hooks/useAsyncData.ts","./src/features/search/hooks/useDistinctValues.ts","./src/features/search/hooks/useSearch.ts","./src/features/search/utils/debounce.ts","./src/features/search/utils/fieldUtils.ts","./src/features/search/utils/filterUtils.ts","./src/features/search/utils/sortUtils.ts","./src/hooks/useAsyncData.ts","./src/lib/utils.ts","./src/pages/AccountObjectDetailPage.tsx","./src/pages/AccountSearch.tsx","./src/pages/Home.tsx","./src/pages/NotFound.tsx","./src/types/conversation.ts","./src/types/globals.d.ts","./src/utils/accountFields.ts","./e2e/app.spec.ts","./vite-env.d.ts","./vitest-env.d.ts","./vitest.setup.ts","../../../../../../../../../sdk/platform-sdk/types/env.d.ts"],"version":"5.9.3"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/ui-bundle-template-base-sfdx-project",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.53.1",
|
|
4
4
|
"description": "Base SFDX project template",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"publishConfig": {
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
"prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
|
|
22
22
|
"prettier:verify": "prettier --check \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
|
|
23
23
|
"precommit": "lint-staged",
|
|
24
|
-
"setup": "node scripts/org-setup.mjs"
|
|
24
|
+
"setup": "node scripts/org-setup.mjs",
|
|
25
|
+
"dev:preview": "node scripts/org-setup-dev.mjs"
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
28
|
+
"fast-xml-parser": "^5.9.3",
|
|
27
29
|
"zod": "^3.24.1"
|
|
28
30
|
},
|
|
29
31
|
"devDependencies": {
|
|
@@ -50,11 +50,35 @@ export const ConfigSchema = z
|
|
|
50
50
|
// No siteName: the site is derived from the single
|
|
51
51
|
// networks/<siteName>.network-meta.xml the app ships (see spec §5.2),
|
|
52
52
|
// exactly like the guestUser permset path.
|
|
53
|
+
//
|
|
54
|
+
// selfRegProfile also drives the M1 license pre-check (W-23043735):
|
|
55
|
+
// setup derives the required UserLicense from this profile
|
|
56
|
+
// (Profile.UserLicense, matched on the stable LicenseDefinitionKey) and
|
|
57
|
+
// warns + skips self-registration when the org lacks it or has no seats.
|
|
58
|
+
// No separate license field is declared — the requirement can't drift
|
|
59
|
+
// from the profile the flow actually assigns.
|
|
53
60
|
selfRegProfile: z.string().min(1),
|
|
54
61
|
accountName: z.string().min(1),
|
|
55
62
|
})
|
|
56
63
|
.strict()
|
|
57
64
|
.optional(),
|
|
65
|
+
socialLogin: z
|
|
66
|
+
.object({
|
|
67
|
+
// Profile to add to NetworkMemberGroup so SSO-registered users can access
|
|
68
|
+
// the community (e.g. "Customer Community User"). Also enables the
|
|
69
|
+
// "Allow standard external profiles" org setting.
|
|
70
|
+
communityMemberProfile: z.string().min(1),
|
|
71
|
+
// DeveloperName of AuthProvider (OAuth) or SamlSsoConfig (SAML) records to link to the site's AuthConfig.
|
|
72
|
+
// Required because React (Site Container) sites hide SSO config in Admin UI.
|
|
73
|
+
authProviderNames: z.array(z.string().min(1)).min(1),
|
|
74
|
+
// Permission set to assign to community users created via SSO.
|
|
75
|
+
// Required because getCurrentUser() calls /chatter/users/me which needs
|
|
76
|
+
// API access (PermissionsApiEnabled) that the community profile lacks.
|
|
77
|
+
// Typically the app's "*_Guest_User_Api_Access" permset.
|
|
78
|
+
communityUserPermset: z.string().min(1).optional(),
|
|
79
|
+
})
|
|
80
|
+
.strict()
|
|
81
|
+
.optional(),
|
|
58
82
|
})
|
|
59
83
|
.strict();
|
|
60
84
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Dev preview: refresh the GraphQL schema/types against a target org, then launch
|
|
4
|
+
* the Vite dev server (spec §5.5, M4). This is the step that used to be the final
|
|
5
|
+
* `dev` stage of org-setup.mjs — extracted here so `npm run setup` terminates
|
|
6
|
+
* cleanly after graphql, and the long-lived dev server is an explicit, separate
|
|
7
|
+
* `npm run dev:preview`.
|
|
8
|
+
*
|
|
9
|
+
* Unlike setup, this does NOT log in or deploy — it assumes the org is already
|
|
10
|
+
* set up. It shares org/bundle resolution and the process runner with org-setup
|
|
11
|
+
* via org-setup-utils.mjs.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* npm run dev:preview # prompt to pick an org + bundle
|
|
15
|
+
* npm run dev:preview -- --target-org myorg
|
|
16
|
+
* npm run dev:preview -- --target-org myorg --ui-bundle-name my-app
|
|
17
|
+
*
|
|
18
|
+
* Flow (in order):
|
|
19
|
+
* 1. resolve target org (explicit --target-org, else prompt / default org)
|
|
20
|
+
* 2. resolve UI bundle (explicit --ui-bundle-name, else picker / warning)
|
|
21
|
+
* 3. npm install (in the UI bundle)
|
|
22
|
+
* 4. npm run graphql:schema (SF_TARGET_ORG=<org>) — introspect the live schema
|
|
23
|
+
* 5. npm run graphql:codegen — regenerate typed operations
|
|
24
|
+
* 6. npm run dev (blocking, Ctrl+C to stop)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { resolve, dirname } from 'node:path';
|
|
28
|
+
import { fileURLToPath } from 'node:url';
|
|
29
|
+
|
|
30
|
+
import { run, resolveSfdxSource, discoverUIBundleDir, resolveTargetOrg } from './org-setup-utils.mjs';
|
|
31
|
+
|
|
32
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
const ROOT = resolve(__dirname, '..');
|
|
34
|
+
|
|
35
|
+
function parseArgs() {
|
|
36
|
+
const args = process.argv.slice(2);
|
|
37
|
+
let targetOrg = null;
|
|
38
|
+
let uiBundleName = null;
|
|
39
|
+
for (let i = 0; i < args.length; i++) {
|
|
40
|
+
if (args[i] === '--target-org' && args[i + 1]) {
|
|
41
|
+
targetOrg = args[++i];
|
|
42
|
+
} else if (args[i] === '--ui-bundle-name' && args[i + 1]) {
|
|
43
|
+
uiBundleName = args[++i];
|
|
44
|
+
} else if (args[i] === '--help' || args[i] === '-h') {
|
|
45
|
+
console.log(`
|
|
46
|
+
Dev preview — refresh GraphQL types then launch the Vite dev server
|
|
47
|
+
|
|
48
|
+
Usage:
|
|
49
|
+
npm run dev:preview -- [--target-org <alias>] [--ui-bundle-name <name>]
|
|
50
|
+
|
|
51
|
+
Options:
|
|
52
|
+
--target-org <alias> Target Salesforce org alias. If omitted, you are prompted
|
|
53
|
+
to pick from authenticated orgs (or the default org is used).
|
|
54
|
+
--ui-bundle-name <name> UI bundle folder under uiBundles/ (default: auto-detect / prompt)
|
|
55
|
+
-h, --help Show this help
|
|
56
|
+
`);
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { targetOrg, uiBundleName };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function main() {
|
|
64
|
+
const parsed = parseArgs();
|
|
65
|
+
|
|
66
|
+
const targetOrg = await resolveTargetOrg(parsed);
|
|
67
|
+
const uiBundlesDir = resolve(resolveSfdxSource(ROOT), 'uiBundles');
|
|
68
|
+
const uiBundleDir = await discoverUIBundleDir(uiBundlesDir, parsed.uiBundleName);
|
|
69
|
+
|
|
70
|
+
console.log('Dev preview — target org:', targetOrg, '| UI bundle:', uiBundleDir);
|
|
71
|
+
|
|
72
|
+
run('UI Bundle npm install', 'npm', ['install'], { cwd: uiBundleDir });
|
|
73
|
+
run('GraphQL schema (introspect)', 'npm', ['run', 'graphql:schema'], {
|
|
74
|
+
cwd: uiBundleDir,
|
|
75
|
+
env: { ...process.env, SF_TARGET_ORG: targetOrg },
|
|
76
|
+
});
|
|
77
|
+
run('GraphQL codegen', 'npm', ['run', 'graphql:codegen'], { cwd: uiBundleDir });
|
|
78
|
+
|
|
79
|
+
console.log('\n--- Launching dev server (Ctrl+C to stop) ---\n');
|
|
80
|
+
const devResult = run('Dev server', 'npm', ['run', 'dev'], { cwd: uiBundleDir, optional: true });
|
|
81
|
+
process.exit(devResult.status ?? 0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
main().catch((err) => {
|
|
85
|
+
console.error(err);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|