@salesforce/webapp-template-feature-react-global-search-experimental 1.3.3
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 +415 -0
- package/dist/.a4drules/build-validation.md +81 -0
- package/dist/.a4drules/code-quality.md +150 -0
- package/dist/.a4drules/graphql/tools/knowledge/lds-explore-graphql-schema.md +227 -0
- package/dist/.a4drules/graphql/tools/knowledge/lds-generate-graphql-mutationquery.md +211 -0
- package/dist/.a4drules/graphql/tools/knowledge/lds-generate-graphql-readquery.md +185 -0
- package/dist/.a4drules/graphql/tools/knowledge/lds-guide-graphql.md +205 -0
- package/dist/.a4drules/graphql/tools/schemas/shared.graphqls +1150 -0
- package/dist/.a4drules/graphql.md +98 -0
- package/dist/.a4drules/images.md +13 -0
- package/dist/.a4drules/react.md +361 -0
- package/dist/.a4drules/react_image_processing.md +45 -0
- package/dist/.a4drules/typescript.md +224 -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/CHANGELOG.md +11 -0
- package/dist/README.md +18 -0
- package/dist/config/project-scratch-def.json +13 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/.prettierignore +9 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/.prettierrc +11 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/eslint.config.js +113 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/feature-react-global-search.webapplication-meta.xml +7 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/index.html +13 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/package.json +42 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/api/graphql-operations-types.ts +127 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/api/objectInfoService.ts +229 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/api/utils/query/highRevenueAccountsQuery.graphql +29 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/app.tsx +13 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/appLayout.tsx +9 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/icons/book.svg +3 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/icons/copy.svg +4 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/icons/rocket.svg +3 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/icons/star.svg +3 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/images/codey-1.png +0 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/images/codey-2.png +0 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/images/codey-3.png +0 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/assets/images/vibe-codey.svg +194 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/FiltersPanel.tsx +373 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/LoadingFallback.tsx +61 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/SearchResultCard.tsx +127 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/alerts/status-alert.tsx +45 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/detail/DetailFields.tsx +57 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/detail/DetailHeader.tsx +42 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/filters/FilterField.tsx +54 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/filters/FilterInput.tsx +55 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/filters/FilterSelect.tsx +72 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/forms/filters-form.tsx +114 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/forms/submit-button.tsx +47 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/layout/card-layout.tsx +19 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/search/ResultCardFields.tsx +71 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/search/SearchHeader.tsx +23 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/search/SearchPagination.tsx +162 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/search/SearchResultsPanel.tsx +184 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/shared/GlobalSearchInput.tsx +110 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/alert.tsx +65 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/button.tsx +56 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/card.tsx +77 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/field.tsx +111 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/index.ts +71 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/input.tsx +19 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/label.tsx +19 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/pagination.tsx +99 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/select.tsx +151 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/skeleton.tsx +7 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/spinner.tsx +21 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/table.tsx +114 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/components/ui/tabs.tsx +115 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/constants.ts +36 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/features/global-search/index.ts +65 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/hooks/form.tsx +208 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/hooks/useObjectSearchData.ts +419 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/hooks/useRecordDetail.ts +127 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/lib/utils.ts +6 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/pages/About.tsx +12 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/pages/DetailPage.tsx +128 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/pages/GlobalSearch.tsx +173 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/pages/Home.tsx +13 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/pages/NotFound.tsx +18 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/routes.tsx +50 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/styles/global.css +108 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/types/filters/filters.ts +122 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/types/filters/picklist.ts +32 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/types/objectInfo/objectInfo.ts +166 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/types/search/searchResults.ts +228 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/apiUtils.ts +125 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/cacheUtils.ts +76 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/debounce.ts +89 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/fieldUtils.ts +186 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/fieldValueExtractor.ts +67 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/filterUtils.ts +32 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/formUtils.ts +130 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/paginationUtils.ts +49 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/recordUtils.ts +75 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/src/utils/sanitizationUtils.ts +49 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/tsconfig.json +36 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/tsconfig.node.json +13 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/vite-env.d.ts +1 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/vite.config.ts +82 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/vitest-env.d.ts +2 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/vitest.config.ts +11 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/vitest.setup.ts +1 -0
- package/dist/force-app/main/default/webapplications/feature-react-global-search/webapplication.json +7 -0
- package/dist/jest.config.js +6 -0
- package/dist/package.json +37 -0
- package/dist/scripts/apex/hello.apex +10 -0
- package/dist/scripts/soql/account.soql +6 -0
- package/dist/sfdx-project.json +12 -0
- package/package.json +32 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Terms of Use
|
|
2
|
+
|
|
3
|
+
Copyright 2026 Salesforce, Inc. All rights reserved.
|
|
4
|
+
|
|
5
|
+
These Terms of Use govern the download, installation, and/or use of this
|
|
6
|
+
software provided by Salesforce, Inc. ("Salesforce") (the "Software"), were
|
|
7
|
+
last updated on April 15, 2025, and constitute a legally binding
|
|
8
|
+
agreement between you and Salesforce. If you do not agree to these Terms of
|
|
9
|
+
Use, do not install or use the Software.
|
|
10
|
+
|
|
11
|
+
Salesforce grants you a worldwide, non-exclusive, no-charge, royalty-free
|
|
12
|
+
copyright license to reproduce, prepare derivative works of, publicly
|
|
13
|
+
display, publicly perform, sublicense, and distribute the Software and
|
|
14
|
+
derivative works subject to these Terms. These Terms shall be included in
|
|
15
|
+
all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
Subject to the limited rights expressly granted hereunder, Salesforce
|
|
18
|
+
reserves all rights, title, and interest in and to all intellectual
|
|
19
|
+
property subsisting in the Software. No rights are granted to you hereunder
|
|
20
|
+
other than as expressly set forth herein. Users residing in countries on
|
|
21
|
+
the United States Office of Foreign Assets Control sanction list, or which
|
|
22
|
+
are otherwise subject to a US export embargo, may not use the Software.
|
|
23
|
+
|
|
24
|
+
Implementation of the Software may require development work, for which you
|
|
25
|
+
are responsible. The Software may contain bugs, errors and
|
|
26
|
+
incompatibilities and is made available on an AS IS basis without support,
|
|
27
|
+
updates, or service level commitments.
|
|
28
|
+
|
|
29
|
+
Salesforce reserves the right at any time to modify, suspend, or
|
|
30
|
+
discontinue, the Software (or any part thereof) with or without notice. You
|
|
31
|
+
agree that Salesforce shall not be liable to you or to any third party for
|
|
32
|
+
any modification, suspension, or discontinuance.
|
|
33
|
+
|
|
34
|
+
You agree to defend Salesforce against any claim, demand, suit or
|
|
35
|
+
proceeding made or brought against Salesforce by a third party arising out
|
|
36
|
+
of or accruing from (a) your use of the Software, and (b) any application
|
|
37
|
+
you develop with the Software that infringes any copyright, trademark,
|
|
38
|
+
trade secret, trade dress, patent, or other intellectual property right of
|
|
39
|
+
any person or defames any person or violates their rights of publicity or
|
|
40
|
+
privacy (each a "Claim Against Salesforce"), and will indemnify Salesforce
|
|
41
|
+
from any damages, attorney fees, and costs finally awarded against
|
|
42
|
+
Salesforce as a result of, or for any amounts paid by Salesforce under a
|
|
43
|
+
settlement approved by you in writing of, a Claim Against Salesforce,
|
|
44
|
+
provided Salesforce (x) promptly gives you written notice of the Claim
|
|
45
|
+
Against Salesforce, (y) gives you sole control of the defense and
|
|
46
|
+
settlement of the Claim Against Salesforce (except that you may not settle
|
|
47
|
+
any Claim Against Salesforce unless it unconditionally releases Salesforce
|
|
48
|
+
of all liability), and (z) gives you all reasonable assistance, at your
|
|
49
|
+
expense.
|
|
50
|
+
|
|
51
|
+
WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE SOFTWARE IS NOT
|
|
52
|
+
SUPPORTED AND IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
53
|
+
IMPLIED. IN NO EVENT SHALL SALESFORCE HAVE ANY LIABILITY FOR ANY DAMAGES,
|
|
54
|
+
INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
|
|
55
|
+
PUNITIVE, OR CONSEQUENTIAL DAMAGES, OR DAMAGES BASED ON LOST PROFITS, DATA,
|
|
56
|
+
OR USE, IN CONNECTION WITH THE SOFTWARE, HOWEVER CAUSED AND WHETHER IN
|
|
57
|
+
CONTRACT, TORT, OR UNDER ANY OTHER THEORY OF LIABILITY, WHETHER OR NOT YOU
|
|
58
|
+
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
59
|
+
|
|
60
|
+
These Terms of Use shall be governed exclusively by the internal laws of
|
|
61
|
+
the State of California, without regard to its conflicts of laws
|
|
62
|
+
rules. Each party hereby consents to the exclusive jurisdiction of the
|
|
63
|
+
state and federal courts located in San Francisco County, California to
|
|
64
|
+
adjudicate any dispute arising out of or relating to these Terms of Use and
|
|
65
|
+
the download, installation, and/or use of the Software. Except as expressly
|
|
66
|
+
stated herein, these Terms of Use constitute the entire agreement between
|
|
67
|
+
the parties, and supersede all prior and contemporaneous agreements,
|
|
68
|
+
proposals, or representations, written or oral, concerning their subject
|
|
69
|
+
matter. No modification, amendment, or waiver of any provision of these
|
|
70
|
+
Terms of Use shall be effective unless it is by an update to these Terms of
|
|
71
|
+
Use that Salesforce makes available, or is in writing and signed by the
|
|
72
|
+
party against whom the modification, amendment, or waiver is to be
|
|
73
|
+
asserted.
|
|
74
|
+
|
|
75
|
+
Data Privacy: Salesforce may collect, process, and store device,
|
|
76
|
+
system, and other information related to your use of the Software. This
|
|
77
|
+
information includes, but is not limited to, IP address, user metrics, and
|
|
78
|
+
other data ("Usage Data"). Salesforce may use Usage Data for analytics,
|
|
79
|
+
product development, and marketing purposes. You acknowledge that files
|
|
80
|
+
generated in conjunction with the Software may contain sensitive or
|
|
81
|
+
confidential data, and you are solely responsible for anonymizing and
|
|
82
|
+
protecting such data.
|
package/README.md
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
# Feature: Global Search
|
|
2
|
+
|
|
3
|
+
This feature provides API services and utilities for implementing global search functionality in Salesforce Web Applications. It includes:
|
|
4
|
+
|
|
5
|
+
- **API Service Layer** - Type-safe API client for Salesforce search endpoints
|
|
6
|
+
- **Type Definitions** - Complete TypeScript types with Zod schema validation
|
|
7
|
+
- **Utility Functions** - Helper functions for debouncing and data extraction
|
|
8
|
+
- **Custom Hooks** - React hooks for managing search data and API calls
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Multi-Object Search API** - Search across multiple Salesforce objects simultaneously
|
|
13
|
+
- **Object Metadata API** - Fetch object information, column definitions, and filter definitions
|
|
14
|
+
- **Picklist Values API** - Retrieve picklist values for dynamic filter options
|
|
15
|
+
- **Type Safety** - Full TypeScript support with Zod schema validation
|
|
16
|
+
- **Race Condition Protection** - AbortSignal support to cancel stale requests
|
|
17
|
+
- **Error Handling** - Consistent error handling across all API calls
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
### API Service Layer
|
|
22
|
+
|
|
23
|
+
The feature includes a state-agnostic service layer (`objectInfoService`) that provides pure functions for API interactions. All API calls:
|
|
24
|
+
|
|
25
|
+
- Use `fetchAndValidate` utility for consistent error handling
|
|
26
|
+
- Support `AbortSignal` for request cancellation
|
|
27
|
+
- Validate responses with Zod schemas
|
|
28
|
+
- Provide type-safe return values
|
|
29
|
+
|
|
30
|
+
### API Flow Diagram
|
|
31
|
+
|
|
32
|
+
The following flowchart explains the API architecture and how each API is consumed:
|
|
33
|
+
|
|
34
|
+
```mermaid
|
|
35
|
+
flowchart TD
|
|
36
|
+
Start([Application Initialization]) --> BatchAPI[getObjectInfoBatch API]
|
|
37
|
+
BatchAPI -->|Comma-separated Object Names| ObjectMetadata[Object Metadata]
|
|
38
|
+
ObjectMetadata --> LoadObjectData[Load Data for Each Object]
|
|
39
|
+
|
|
40
|
+
%% Parallel API Calls for Each Object
|
|
41
|
+
LoadObjectData --> ParallelAPIs{Parallel API Calls per Object}
|
|
42
|
+
|
|
43
|
+
%% List Info API
|
|
44
|
+
ParallelAPIs --> ListInfoAPI[getObjectListInfo API]
|
|
45
|
+
ListInfoAPI -->|Object Name + __SearchResult| Columns[Column Definitions]
|
|
46
|
+
|
|
47
|
+
%% Filters API
|
|
48
|
+
ParallelAPIs --> FiltersAPI[getObjectListFilters API]
|
|
49
|
+
FiltersAPI -->|Object Name| Filters[Filter Definitions]
|
|
50
|
+
|
|
51
|
+
%% Search Results API
|
|
52
|
+
ParallelAPIs --> SearchAPI[searchResults API]
|
|
53
|
+
SearchAPI -->|Query + Object Name + Pagination| SearchRecords[Search Records]
|
|
54
|
+
|
|
55
|
+
%% Picklist Values Flow
|
|
56
|
+
Filters --> PicklistCheck{Has Picklist Fields?}
|
|
57
|
+
PicklistCheck -->|Yes| PicklistAPI[getPicklistValues API]
|
|
58
|
+
PicklistAPI -->|Object Name + Field Name| PicklistValues[Picklist Options]
|
|
59
|
+
PicklistCheck -->|No| SkipPicklist[Skip Picklist Fetch]
|
|
60
|
+
|
|
61
|
+
%% User Interactions - API Calls
|
|
62
|
+
UserQuery([User Search Query]) --> Debounce[Debounce 500ms]
|
|
63
|
+
Debounce --> SearchAPI
|
|
64
|
+
|
|
65
|
+
FilterChange([Filter Change]) --> SearchAPI
|
|
66
|
+
PageChange([Pagination Change]) --> SearchAPI
|
|
67
|
+
PageSizeChange([Page Size Change]) --> SearchAPI
|
|
68
|
+
|
|
69
|
+
%% Error Handling
|
|
70
|
+
BatchAPI -.->|Error| ErrorHandler[Error Handler]
|
|
71
|
+
ListInfoAPI -.->|Error| ErrorHandler
|
|
72
|
+
FiltersAPI -.->|Error| ErrorHandler
|
|
73
|
+
SearchAPI -.->|Error| ErrorHandler
|
|
74
|
+
PicklistAPI -.->|Error| ErrorHandler
|
|
75
|
+
ErrorHandler --> HandleError[Handle Error Gracefully]
|
|
76
|
+
|
|
77
|
+
%% Race Condition Protection
|
|
78
|
+
SearchAPI -.->|AbortSignal| CancelOld[Cancel Old Request]
|
|
79
|
+
CancelOld --> PreventStale[Prevent Stale Data]
|
|
80
|
+
|
|
81
|
+
style BatchAPI fill:#e1f5ff
|
|
82
|
+
style ListInfoAPI fill:#e1f5ff
|
|
83
|
+
style FiltersAPI fill:#e1f5ff
|
|
84
|
+
style SearchAPI fill:#e1f5ff
|
|
85
|
+
style PicklistAPI fill:#e1f5ff
|
|
86
|
+
style ErrorHandler fill:#ffe1e1
|
|
87
|
+
style CancelOld fill:#fff4e1
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## API Reference
|
|
91
|
+
|
|
92
|
+
### 1. `getObjectInfoBatch(objectApiNames, signal?)`
|
|
93
|
+
|
|
94
|
+
**Purpose**: Fetches object metadata for multiple Salesforce objects in a single request.
|
|
95
|
+
|
|
96
|
+
**When to Use**:
|
|
97
|
+
|
|
98
|
+
- Initial page load to get object labels and basic metadata
|
|
99
|
+
- Needed to create tabs for each object type
|
|
100
|
+
- Provides object plural labels for tab display
|
|
101
|
+
|
|
102
|
+
**Parameters**:
|
|
103
|
+
|
|
104
|
+
- `objectApiNames`: Comma-separated list (e.g., `"Account,Property__c"`)
|
|
105
|
+
- `signal?`: Optional AbortSignal for cancellation
|
|
106
|
+
|
|
107
|
+
**Returns**: `ObjectInfoBatchResponse` containing metadata for all requested objects
|
|
108
|
+
|
|
109
|
+
**Example**:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const objectInfo = await getObjectInfoBatch("Account,Property__c");
|
|
113
|
+
// Returns: { objects: [{ apiName: 'Account', label: 'Accounts', ... }, ...] }
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**API Endpoint**: `GET /object-info/batch/{objectApiNames}`
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### 2. `getObjectListInfo(objectApiName, listViewApiName, signal?)`
|
|
121
|
+
|
|
122
|
+
**Purpose**: Fetches column definitions for search results.
|
|
123
|
+
|
|
124
|
+
**When to Use**:
|
|
125
|
+
|
|
126
|
+
- When loading data for an object to determine which columns are available
|
|
127
|
+
- Provides column metadata (field API names, labels, sortability)
|
|
128
|
+
- Used to understand the structure of search results
|
|
129
|
+
|
|
130
|
+
**Parameters**:
|
|
131
|
+
|
|
132
|
+
- `objectApiName`: The object API name (e.g., `"Account"`)
|
|
133
|
+
- `listViewApiName`: Always `"__SearchResult"` for search results
|
|
134
|
+
- `signal?`: Optional AbortSignal for cancellation
|
|
135
|
+
|
|
136
|
+
**Returns**: Array of `Column` objects with field information
|
|
137
|
+
|
|
138
|
+
**Example**:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
const columns = await getObjectListInfo("Account", "__SearchResult");
|
|
142
|
+
// Returns: [{ fieldApiName: 'Name', label: 'Account Name', sortable: true, ... }, ...]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**API Endpoint**: `GET /list-info/{objectApiName}/{listViewApiName}`
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### 3. `getObjectListFilters(objectApiName, signal?)`
|
|
150
|
+
|
|
151
|
+
**Purpose**: Fetches filter definitions for a specific object.
|
|
152
|
+
|
|
153
|
+
**When to Use**:
|
|
154
|
+
|
|
155
|
+
- When loading data for an object to determine available filters
|
|
156
|
+
- Provides filter metadata (field types, operators, default values, affordances)
|
|
157
|
+
- Used to understand what filters can be applied to search results
|
|
158
|
+
|
|
159
|
+
**Parameters**:
|
|
160
|
+
|
|
161
|
+
- `objectApiName`: The object API name (e.g., `"Account"`)
|
|
162
|
+
- `signal?`: Optional AbortSignal for cancellation
|
|
163
|
+
|
|
164
|
+
**Returns**: Array of `Filter` objects with filter definitions
|
|
165
|
+
|
|
166
|
+
**Example**:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const filters = await getObjectListFilters("Account");
|
|
170
|
+
// Returns: [{ targetFieldPath: 'Name', operator: 'contains', ... }, ...]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**API Endpoint**: `GET /search-info/{objectApiName}/filters`
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### 4. `getPicklistValues(objectApiName, fieldName, recordTypeId?, signal?)`
|
|
178
|
+
|
|
179
|
+
**Purpose**: Fetches available picklist values for a specific field.
|
|
180
|
+
|
|
181
|
+
**When to Use**:
|
|
182
|
+
|
|
183
|
+
- When a filter has `affordance: 'select'` (indicating a picklist field)
|
|
184
|
+
- Needed to get the list of valid values for a picklist filter
|
|
185
|
+
- Called for each picklist field in the filters array returned by `getObjectListFilters`
|
|
186
|
+
|
|
187
|
+
**Parameters**:
|
|
188
|
+
|
|
189
|
+
- `objectApiName`: The object API name (e.g., `"Account"`)
|
|
190
|
+
- `fieldName`: The field API name (e.g., `"Type"`)
|
|
191
|
+
- `recordTypeId?`: Optional record type ID (defaults to master record type)
|
|
192
|
+
- `signal?`: Optional AbortSignal for cancellation
|
|
193
|
+
|
|
194
|
+
**Returns**: Array of `PicklistValue` objects with label and value
|
|
195
|
+
|
|
196
|
+
**Example**:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
const picklistValues = await getPicklistValues("Account", "Type");
|
|
200
|
+
// Returns: [{ label: 'Customer', value: 'Customer' }, { label: 'Partner', value: 'Partner' }, ...]
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**API Endpoint**: `GET /object-info/{objectApiName}/picklist-values/{recordTypeId}/{fieldName}`
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
### 5. `searchResults(query, objectApiName, params?, signal?)`
|
|
208
|
+
|
|
209
|
+
**Purpose**: Performs keyword search on a specific object and returns matching records.
|
|
210
|
+
|
|
211
|
+
**When to Use**:
|
|
212
|
+
|
|
213
|
+
- When executing a search query for a specific object
|
|
214
|
+
- When filters are applied (query should include filter criteria)
|
|
215
|
+
- When pagination changes (use `pageToken` parameter)
|
|
216
|
+
- When page size changes (use `pageSize` parameter)
|
|
217
|
+
- Returns the actual search results with field values
|
|
218
|
+
|
|
219
|
+
**Parameters**:
|
|
220
|
+
|
|
221
|
+
- `query`: The search query string
|
|
222
|
+
- `objectApiName`: The object API name to search (e.g., `"Account"`)
|
|
223
|
+
- `params?`: Optional pagination parameters (`pageSize`, `pageToken`)
|
|
224
|
+
- `signal?`: Optional AbortSignal for cancellation (critical for race condition prevention)
|
|
225
|
+
|
|
226
|
+
**Returns**: Array of `SearchResultRecord` objects with field values
|
|
227
|
+
|
|
228
|
+
**Example**:
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
const results = await searchResults("Acme", "Account", { pageSize: 25, pageToken: "0" });
|
|
232
|
+
// Returns: [{ id: '001...', fields: { Name: 'Acme Corp', ... }, ... }, ...]
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**API Endpoint**: `POST /search/results/keyword?q={query}&objectApiName={objectApiName}`
|
|
236
|
+
|
|
237
|
+
**Request Body**:
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"pageSize": 25,
|
|
242
|
+
"pageToken": "0"
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## API Consumption Flow
|
|
249
|
+
|
|
250
|
+
### Initialization
|
|
251
|
+
|
|
252
|
+
1. **`getObjectInfoBatch`** is called with all object names from `OBJECT_API_NAMES`
|
|
253
|
+
- Returns object metadata (labels, plural labels, etc.)
|
|
254
|
+
- Use this to understand which objects are available for search
|
|
255
|
+
|
|
256
|
+
2. **For each object** (can be done in parallel):
|
|
257
|
+
- **`getObjectListInfo`** - Gets column definitions for search results
|
|
258
|
+
- **`getObjectListFilters`** - Gets filter definitions
|
|
259
|
+
- **`searchResults`** - Gets initial search results (if query is provided)
|
|
260
|
+
|
|
261
|
+
3. **For each picklist filter** (can be done in parallel):
|
|
262
|
+
- **`getPicklistValues`** - Gets available values for picklist fields
|
|
263
|
+
|
|
264
|
+
### Search Execution
|
|
265
|
+
|
|
266
|
+
1. **Initial Search**:
|
|
267
|
+
- Call **`searchResults`** with the search query and object API name
|
|
268
|
+
- Include pagination parameters (`pageSize`, `pageToken`)
|
|
269
|
+
|
|
270
|
+
2. **Filter Application**:
|
|
271
|
+
- Apply filters to the search query
|
|
272
|
+
- Call **`searchResults`** with updated query/filters
|
|
273
|
+
- Reset pagination to page 1 (use `pageToken: '0'`)
|
|
274
|
+
|
|
275
|
+
3. **Pagination**:
|
|
276
|
+
- Use `pageToken` from previous response for next page
|
|
277
|
+
- Call **`searchResults`** with new `pageToken`
|
|
278
|
+
|
|
279
|
+
4. **Page Size Change**:
|
|
280
|
+
- Call **`searchResults`** with new `pageSize`
|
|
281
|
+
- Reset to page 1 (use `pageToken: '0'`)
|
|
282
|
+
|
|
283
|
+
### Race Condition Prevention
|
|
284
|
+
|
|
285
|
+
All API calls support `AbortSignal` to prevent stale data:
|
|
286
|
+
|
|
287
|
+
- When a new search is triggered, cancel the previous request using `AbortSignal`
|
|
288
|
+
- When switching between objects, cancel previous object requests
|
|
289
|
+
- When component unmounts, cancel all pending requests
|
|
290
|
+
|
|
291
|
+
This ensures applications always work with the most recent data and avoid race conditions.
|
|
292
|
+
|
|
293
|
+
## Setup
|
|
294
|
+
|
|
295
|
+
### Prerequisites
|
|
296
|
+
|
|
297
|
+
1. **Salesforce CLI (`sf`)** - Must be installed and authenticated to a Salesforce org
|
|
298
|
+
2. **@salesforce/webapps packages** - Required for API proxy functionality (see linking instructions below)
|
|
299
|
+
|
|
300
|
+
### Linking @salesforce/webapps (Required until packages are published)
|
|
301
|
+
|
|
302
|
+
Since `@salesforce/webapps` and `@salesforce/vite-plugin-webapps` are not yet published to npm, you need to link them locally:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Step 1: In the webapps repo - register packages with npm's link registry
|
|
306
|
+
cd /path/to/webapps/packages/webapps && npm link
|
|
307
|
+
cd /path/to/webapps/packages/vite-plugin-webapps && npm link
|
|
308
|
+
|
|
309
|
+
# Step 2: In this repo - link the packages
|
|
310
|
+
cd /path/to/webapps-templates/packages/feature/feature-react-global-search
|
|
311
|
+
npm link @salesforce/webapps
|
|
312
|
+
npm link @salesforce/vite-plugin-webapps
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Building and Running
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# Build the feature (applies patches from template to dist)
|
|
319
|
+
npm run build
|
|
320
|
+
|
|
321
|
+
# Start the development server
|
|
322
|
+
npm run dev
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The `npm run build` command will:
|
|
326
|
+
|
|
327
|
+
1. Apply feature patches to create the dist directory
|
|
328
|
+
2. Remove the package-lock.json (to avoid resolution conflicts)
|
|
329
|
+
3. Re-link the @salesforce/webapps packages
|
|
330
|
+
|
|
331
|
+
## Configuration
|
|
332
|
+
|
|
333
|
+
### Setting Searchable Objects
|
|
334
|
+
|
|
335
|
+
Configure which Salesforce objects to search by editing `src/constants.ts`:
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
export const OBJECT_API_NAMES = ["Account", "Property__c"] as const;
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
This configuration determines which objects will be included when calling `getObjectInfoBatch` and when executing searches.
|
|
342
|
+
|
|
343
|
+
## Usage
|
|
344
|
+
|
|
345
|
+
### Using the API Service
|
|
346
|
+
|
|
347
|
+
Import the service and use the available methods:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import { objectInfoService } from "@/api/objectInfoService";
|
|
351
|
+
|
|
352
|
+
// Get object metadata
|
|
353
|
+
const objectInfo = await objectInfoService.getObjectInfoBatch("Account,Property__c");
|
|
354
|
+
|
|
355
|
+
// Get column definitions
|
|
356
|
+
const columns = await objectInfoService.getObjectListInfo("Account", "__SearchResult");
|
|
357
|
+
|
|
358
|
+
// Get filter definitions
|
|
359
|
+
const filters = await objectInfoService.getObjectListFilters("Account");
|
|
360
|
+
|
|
361
|
+
// Get picklist values
|
|
362
|
+
const picklistValues = await objectInfoService.getPicklistValues("Account", "Type");
|
|
363
|
+
|
|
364
|
+
// Execute search
|
|
365
|
+
const results = await objectInfoService.searchResults("Acme", "Account", {
|
|
366
|
+
pageSize: 25,
|
|
367
|
+
pageToken: "0",
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Using the Custom Hook
|
|
372
|
+
|
|
373
|
+
The `useObjectSearchData` hook manages API calls and data fetching:
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
import { useObjectSearchData } from "@/hooks/useObjectSearchData";
|
|
377
|
+
|
|
378
|
+
const { tabs, loading, error, tabData, filtersData } = useObjectSearchData({
|
|
379
|
+
filteredObjectApiNames: ["Account", "Property__c"],
|
|
380
|
+
activeTab: "Account",
|
|
381
|
+
searchQuery: "Acme",
|
|
382
|
+
searchPageSize: 25,
|
|
383
|
+
searchPageToken: "0",
|
|
384
|
+
});
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Type Safety
|
|
388
|
+
|
|
389
|
+
All API responses are validated using Zod schemas, ensuring:
|
|
390
|
+
|
|
391
|
+
- Type safety at compile time
|
|
392
|
+
- Runtime validation of API responses
|
|
393
|
+
- Better error messages when API contracts change
|
|
394
|
+
- Protection against malformed data
|
|
395
|
+
|
|
396
|
+
Type definitions are derived from Zod schemas using `z.infer`, ensuring consistency between validation and TypeScript types.
|
|
397
|
+
|
|
398
|
+
## Error Handling
|
|
399
|
+
|
|
400
|
+
The `fetchAndValidate` utility provides consistent error handling:
|
|
401
|
+
|
|
402
|
+
- Network errors are caught and re-thrown with context
|
|
403
|
+
- HTTP errors (non-200 status) are caught and reported
|
|
404
|
+
- Zod validation errors are caught and reported (without logging sensitive details)
|
|
405
|
+
- AbortErrors are properly propagated (not treated as regular errors)
|
|
406
|
+
|
|
407
|
+
All errors are handled gracefully in the UI, preventing page refreshes and providing user-friendly error messages.
|
|
408
|
+
|
|
409
|
+
## Dependencies
|
|
410
|
+
|
|
411
|
+
This feature depends on:
|
|
412
|
+
|
|
413
|
+
- **feature-shadcn** - For all UI components (Button, Input, Select, Table, Pagination, etc.)
|
|
414
|
+
- **@salesforce/webapps** - For API client and Salesforce integration
|
|
415
|
+
- **zod** - For runtime validation and type inference
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# AI Rule: Build Validation
|
|
2
|
+
|
|
3
|
+
Build validation for successful deployments with minimal friction.
|
|
4
|
+
|
|
5
|
+
## Targets
|
|
6
|
+
- `force-app/main/default/webapplications/*/**/*`
|
|
7
|
+
- `**/*.{js,ts,jsx,tsx}`
|
|
8
|
+
|
|
9
|
+
## MANDATORY: Build Success
|
|
10
|
+
|
|
11
|
+
**Before completing any coding session:**
|
|
12
|
+
```bash
|
|
13
|
+
npm run build # MUST succeed with no errors
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick Quality Checks
|
|
17
|
+
```bash
|
|
18
|
+
npm run format:check # Auto-fixable
|
|
19
|
+
npm run lint # Most issues auto-fixable
|
|
20
|
+
tsc -b # Catches major issues
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
**Must Pass:**
|
|
26
|
+
- `npm run build` completes successfully
|
|
27
|
+
- No TypeScript compilation errors
|
|
28
|
+
- No critical ESLint errors
|
|
29
|
+
|
|
30
|
+
**Can Be Warnings:**
|
|
31
|
+
- ESLint warnings
|
|
32
|
+
- Prettier formatting issues
|
|
33
|
+
- Minor TypeScript warnings
|
|
34
|
+
|
|
35
|
+
## Auto-Fix Commands
|
|
36
|
+
```bash
|
|
37
|
+
npm run fix-all # Fix formatting + linting
|
|
38
|
+
npm run format # Fix Prettier issues
|
|
39
|
+
npm run lint:fix # Fix ESLint issues
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Workflow
|
|
43
|
+
|
|
44
|
+
**During Development:**
|
|
45
|
+
1. Write code with AI assistance
|
|
46
|
+
2. Save frequently (auto-format on save)
|
|
47
|
+
3. Check periodically: `npm run lint` (optional)
|
|
48
|
+
|
|
49
|
+
**Before Completion:**
|
|
50
|
+
1. Run `npm run build`
|
|
51
|
+
2. If fails: Run `npm run fix-all`, fix TypeScript errors, retry build
|
|
52
|
+
|
|
53
|
+
## Error Priority
|
|
54
|
+
|
|
55
|
+
**Fix Immediately:**
|
|
56
|
+
- TypeScript compilation errors
|
|
57
|
+
- Import/export errors
|
|
58
|
+
- Syntax errors
|
|
59
|
+
|
|
60
|
+
**Fix When Convenient:**
|
|
61
|
+
- ESLint warnings
|
|
62
|
+
- Prettier formatting
|
|
63
|
+
- Unused variables
|
|
64
|
+
|
|
65
|
+
## Hard Requirements
|
|
66
|
+
- Build must complete without errors
|
|
67
|
+
- No broken imports
|
|
68
|
+
- Basic TypeScript type safety
|
|
69
|
+
|
|
70
|
+
## Key Commands
|
|
71
|
+
```bash
|
|
72
|
+
npm run dev # Start development
|
|
73
|
+
npm run build # Check deployment readiness
|
|
74
|
+
npm run fix-all # Fix common issues
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Troubleshooting Import Errors
|
|
78
|
+
```bash
|
|
79
|
+
npm install # Check missing dependencies
|
|
80
|
+
# Verify file exists, case sensitivity, export/import match
|
|
81
|
+
```
|