@salesforce/webapp-template-app-react-sample-b2x-experimental 1.68.0 → 1.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CHANGELOG.md +16 -0
- package/dist/force-app/main/default/data/Lease__c.json +13 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/package.json +13 -8
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/applicationApi.ts +78 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/graphqlClient.ts +17 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/index.ts +19 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/leadApi.ts +69 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/maintenanceRequestApi.ts +177 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/objectDetailService.ts +125 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/objectInfoGraphQLService.ts +194 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/objectInfoService.ts +199 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/propertyDetailGraphQL.ts +497 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/propertyListingGraphQL.ts +190 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/recordListGraphQLService.ts +365 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/appLayout.tsx +20 -30
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/FiltersPanel.tsx +375 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/LoadingFallback.tsx +61 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/PropertyListingCard.tsx +164 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/PropertyMap.tsx +113 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/SearchResultCard.tsx +131 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/alerts/status-alert.tsx +45 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/DetailFields.tsx +55 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/DetailForm.tsx +146 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/DetailHeader.tsx +34 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/DetailLayoutSections.tsx +80 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/Section.tsx +108 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/SectionRow.tsx +20 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/UiApiDetailForm.tsx +140 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/FieldValueDisplay.tsx +73 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/FormattedAddress.tsx +29 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/FormattedEmail.tsx +17 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/FormattedPhone.tsx +24 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/FormattedText.tsx +11 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/FormattedUrl.tsx +29 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/detail/formatted/index.ts +6 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/filters/FilterField.tsx +54 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/filters/FilterInput.tsx +55 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/filters/FilterSelect.tsx +72 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/forms/filters-form.tsx +114 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/forms/submit-button.tsx +47 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/layout/card-layout.tsx +19 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/search/ResultCardFields.tsx +71 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/search/SearchHeader.tsx +31 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/search/SearchPagination.tsx +144 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/search/SearchResultsPanel.tsx +197 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/shared/GlobalSearchInput.tsx +114 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/constants.ts +39 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/features/global-search/index.ts +33 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/form.tsx +204 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/index.ts +22 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useGeocode.ts +35 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useMaintenanceRequests.ts +39 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useObjectInfoBatch.ts +65 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useObjectSearchData.ts +395 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyAddresses.ts +36 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyDetail.ts +99 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyListingSearch.ts +75 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyMapMarkers.ts +100 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/usePropertyPrimaryImages.ts +51 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useRecordDetailLayout.ts +156 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useRecordListGraphQL.ts +135 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/hooks/useWeather.ts +173 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Application.tsx +263 -76
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Contact.tsx +158 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Dashboard.tsx +137 -65
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/DetailPage.tsx +109 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/GlobalSearch.tsx +229 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Home.tsx +469 -21
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Maintenance.tsx +244 -95
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertyDetails.tsx +211 -39
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertyListings.tsx +26 -10
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertySearch.tsx +165 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertySearchPlaceholder.tsx +49 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-01.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-02.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-03.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-04.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-05.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-06.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-07.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-08.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-09.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-10.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-11.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-12.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-13.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-14.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-15.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-16.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-17.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-18.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-19.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-20.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-21.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-22.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-23.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-24.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/public/property-25.jpg +0 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/routes.tsx +32 -6
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/styles/global.css +23 -63
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/filters/filters.ts +120 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/filters/picklist.ts +32 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/index.ts +4 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/leaflet.d.ts +17 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/objectInfo/objectInfo.ts +166 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/recordDetail/recordDetail.ts +61 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/types/search/searchResults.ts +229 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/apiUtils.ts +125 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/cacheUtils.ts +76 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/debounce.ts +89 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/fieldUtils.ts +354 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/fieldValueExtractor.ts +67 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/filterUtils.ts +32 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/formDataTransformUtils.ts +260 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/formUtils.ts +142 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/geocode.ts +65 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/graphQLNodeFieldUtils.ts +186 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/graphQLObjectInfoAdapter.ts +319 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/graphQLRecordAdapter.ts +90 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/index.ts +59 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/layoutTransformUtils.ts +236 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/linkUtils.ts +14 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/paginationUtils.ts +49 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/recordUtils.ts +159 -0
- package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/utils/sanitizationUtils.ts +49 -0
- package/dist/package.json +1 -1
- package/package.json +2 -2
- package/dist/force-app/main/default/classes/MaintenanceRequestListAction.cls +0 -111
- package/dist/force-app/main/default/classes/MaintenanceRequestListAction.cls-meta.xml +0 -6
- package/dist/force-app/main/default/classes/MaintenanceRequestUpdatePriorityAction.cls +0 -93
- package/dist/force-app/main/default/classes/MaintenanceRequestUpdatePriorityAction.cls-meta.xml +0 -6
|
@@ -0,0 +1,194 @@
|
|
|
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 { getDataSDK } from "@salesforce/sdk-data";
|
|
11
|
+
|
|
12
|
+
/** GraphQL objectInfoInputs for requesting picklist values (API v65.0+). Only apiName and fieldNames are sent; record type filtering is done from the response. */
|
|
13
|
+
export interface ObjectInfoInput {
|
|
14
|
+
apiName: string;
|
|
15
|
+
fieldNames?: string[] | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Raw GraphQL response shape for uiapi.objectInfos (flexible for schema casing). */
|
|
19
|
+
export interface ObjectInfosGraphQLResponse {
|
|
20
|
+
uiapi?: {
|
|
21
|
+
objectInfos?: Array<Record<string, unknown>>;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Builds objectInfos query (metadata only). Uses apiNames only — do not pass objectInfoInputs.
|
|
27
|
+
*/
|
|
28
|
+
function buildObjectInfosQuery(): string {
|
|
29
|
+
return `query GetObjectInfos($apiNames: [String!]!) {
|
|
30
|
+
uiapi {
|
|
31
|
+
objectInfos(apiNames: $apiNames) {
|
|
32
|
+
ApiName
|
|
33
|
+
label
|
|
34
|
+
labelPlural
|
|
35
|
+
nameFields
|
|
36
|
+
defaultRecordTypeId
|
|
37
|
+
keyPrefix
|
|
38
|
+
layoutable
|
|
39
|
+
queryable
|
|
40
|
+
searchable
|
|
41
|
+
updateable
|
|
42
|
+
deletable
|
|
43
|
+
createable
|
|
44
|
+
custom
|
|
45
|
+
mruEnabled
|
|
46
|
+
feedEnabled
|
|
47
|
+
fields {
|
|
48
|
+
ApiName
|
|
49
|
+
label
|
|
50
|
+
dataType
|
|
51
|
+
relationshipName
|
|
52
|
+
reference
|
|
53
|
+
compound
|
|
54
|
+
compoundFieldName
|
|
55
|
+
compoundComponentName
|
|
56
|
+
controllingFields
|
|
57
|
+
controllerName
|
|
58
|
+
referenceToInfos {
|
|
59
|
+
ApiName
|
|
60
|
+
nameFields
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
recordTypeInfos {
|
|
64
|
+
recordTypeId
|
|
65
|
+
name
|
|
66
|
+
master
|
|
67
|
+
available
|
|
68
|
+
defaultRecordTypeMapping
|
|
69
|
+
}
|
|
70
|
+
themeInfo {
|
|
71
|
+
color
|
|
72
|
+
iconUrl
|
|
73
|
+
}
|
|
74
|
+
childRelationships {
|
|
75
|
+
relationshipName
|
|
76
|
+
fieldName
|
|
77
|
+
childObjectApiName
|
|
78
|
+
}
|
|
79
|
+
dependentFields {
|
|
80
|
+
controllingField
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Builds objectInfos query with picklist values (API v65.0+).
|
|
89
|
+
* Schema requires objectInfos to be called with either apiNames or objectInfoInputs, not both.
|
|
90
|
+
* This query uses objectInfoInputs only.
|
|
91
|
+
*/
|
|
92
|
+
function buildObjectInfosWithPicklistsQuery(): string {
|
|
93
|
+
return `query GetPicklistValues($objectInfoInputs: [ObjectInfoInput!]!) {
|
|
94
|
+
uiapi {
|
|
95
|
+
objectInfos(objectInfoInputs: $objectInfoInputs) {
|
|
96
|
+
ApiName
|
|
97
|
+
label
|
|
98
|
+
labelPlural
|
|
99
|
+
nameFields
|
|
100
|
+
defaultRecordTypeId
|
|
101
|
+
keyPrefix
|
|
102
|
+
layoutable
|
|
103
|
+
queryable
|
|
104
|
+
searchable
|
|
105
|
+
updateable
|
|
106
|
+
deletable
|
|
107
|
+
createable
|
|
108
|
+
custom
|
|
109
|
+
mruEnabled
|
|
110
|
+
feedEnabled
|
|
111
|
+
fields {
|
|
112
|
+
ApiName
|
|
113
|
+
label
|
|
114
|
+
dataType
|
|
115
|
+
relationshipName
|
|
116
|
+
reference
|
|
117
|
+
compound
|
|
118
|
+
compoundFieldName
|
|
119
|
+
compoundComponentName
|
|
120
|
+
controllingFields
|
|
121
|
+
controllerName
|
|
122
|
+
referenceToInfos {
|
|
123
|
+
ApiName
|
|
124
|
+
nameFields
|
|
125
|
+
}
|
|
126
|
+
... on PicklistField {
|
|
127
|
+
picklistValuesByRecordTypeIDs {
|
|
128
|
+
recordTypeID
|
|
129
|
+
defaultValue {
|
|
130
|
+
value
|
|
131
|
+
}
|
|
132
|
+
picklistValues {
|
|
133
|
+
label
|
|
134
|
+
value
|
|
135
|
+
validFor
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
recordTypeInfos {
|
|
141
|
+
recordTypeId
|
|
142
|
+
name
|
|
143
|
+
master
|
|
144
|
+
available
|
|
145
|
+
defaultRecordTypeMapping
|
|
146
|
+
}
|
|
147
|
+
themeInfo {
|
|
148
|
+
color
|
|
149
|
+
iconUrl
|
|
150
|
+
}
|
|
151
|
+
childRelationships {
|
|
152
|
+
relationshipName
|
|
153
|
+
fieldName
|
|
154
|
+
childObjectApiName
|
|
155
|
+
}
|
|
156
|
+
dependentFields {
|
|
157
|
+
controllingField
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Fetches object metadata for the given objects via GraphQL.
|
|
166
|
+
*
|
|
167
|
+
* @param apiNames - Object API names (e.g. ["Account", "Contact"]).
|
|
168
|
+
* @param options.objectInfoInputs - When set, picklist values for specified fields are included (API v65.0+).
|
|
169
|
+
* @param options.signal - Optional abort signal.
|
|
170
|
+
* @returns Raw uiapi.objectInfos response (adapt to REST shape via graphQLObjectInfosToBatchResponse).
|
|
171
|
+
*/
|
|
172
|
+
export async function getObjectInfosGraphQL(
|
|
173
|
+
apiNames: string[],
|
|
174
|
+
options?: {
|
|
175
|
+
objectInfoInputs?: ObjectInfoInput[] | null;
|
|
176
|
+
signal?: AbortSignal;
|
|
177
|
+
},
|
|
178
|
+
): Promise<ObjectInfosGraphQLResponse> {
|
|
179
|
+
const names = apiNames.length ? apiNames : [];
|
|
180
|
+
const hasInputs = options?.objectInfoInputs != null && options.objectInfoInputs.length > 0;
|
|
181
|
+
const query = hasInputs ? buildObjectInfosWithPicklistsQuery() : buildObjectInfosQuery();
|
|
182
|
+
const variables: Record<string, unknown> = hasInputs
|
|
183
|
+
? { objectInfoInputs: options!.objectInfoInputs }
|
|
184
|
+
: { apiNames: names };
|
|
185
|
+
const data = await getDataSDK();
|
|
186
|
+
const response = await data.graphql?.<ObjectInfosGraphQLResponse>(query, variables);
|
|
187
|
+
|
|
188
|
+
if (response?.errors?.length) {
|
|
189
|
+
const errorMessages = response.errors.map((e) => e.message).join("; ");
|
|
190
|
+
throw new Error(`GraphQL Error: ${errorMessages}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return response?.data ?? ({} as ObjectInfosGraphQLResponse);
|
|
194
|
+
}
|
package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/objectInfoService.ts
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { uiApiClient } from "@salesforce/webapp-experimental/api";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { SearchResultsResponse, KeywordSearchResult } from "../types/search/searchResults";
|
|
4
|
+
import { SearchResultsResponseSchema } from "../types/search/searchResults";
|
|
5
|
+
import { FilterCriteriaArraySchema } from "../types/filters/filters";
|
|
6
|
+
import type { Filter } from "../types/filters/filters";
|
|
7
|
+
import { FilterArraySchema } from "../types/filters/filters";
|
|
8
|
+
import type { PicklistValue } from "../types/filters/picklist";
|
|
9
|
+
import type { ObjectInfoBatchResponse } from "../types/objectInfo/objectInfo";
|
|
10
|
+
import { fetchAndValidate, safeEncodePath } from "../utils/apiUtils";
|
|
11
|
+
import { getObjectInfosGraphQL } from "./objectInfoGraphQLService";
|
|
12
|
+
import {
|
|
13
|
+
graphQLObjectInfosToBatchResponse,
|
|
14
|
+
extractPicklistValuesFromGraphQLObjectInfo,
|
|
15
|
+
} from "../utils/graphQLObjectInfoAdapter";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Object info and search service.
|
|
19
|
+
*
|
|
20
|
+
* - getObjectInfoBatch / getPicklistValues: GraphQL (objectInfoGraphQLService).
|
|
21
|
+
* - getObjectListFilters, searchResults: REST (search-info, search/results).
|
|
22
|
+
* Hooks use this service; components do not call it directly.
|
|
23
|
+
*
|
|
24
|
+
* @module api/objectInfoService
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/** Cache key: sorted, comma-joined object API names. */
|
|
28
|
+
function getObjectInfoBatchCacheKey(objectApiNames: string): string {
|
|
29
|
+
const names = objectApiNames
|
|
30
|
+
.split(",")
|
|
31
|
+
.map((s) => s.trim())
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
return [...names].sort().join(",");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const objectInfoBatchCache = new Map<string, ObjectInfoBatchResponse>();
|
|
37
|
+
const objectInfoBatchInFlight = new Map<string, Promise<ObjectInfoBatchResponse>>();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Fetches batch object information for the specified objects via GraphQL (uiapi.objectInfos).
|
|
41
|
+
* Results are cached by object set so List, Home, and Detail views share one request.
|
|
42
|
+
*
|
|
43
|
+
* @param objectApiNames - Comma-separated list of object API names (e.g., "Account,AccountBrand")
|
|
44
|
+
* @param signal - Optional AbortSignal to cancel the request
|
|
45
|
+
* @returns Promise resolving to the object info batch response (REST-compatible shape)
|
|
46
|
+
*/
|
|
47
|
+
export async function getObjectInfoBatch(
|
|
48
|
+
objectApiNames: string,
|
|
49
|
+
signal?: AbortSignal,
|
|
50
|
+
): Promise<ObjectInfoBatchResponse> {
|
|
51
|
+
const names = objectApiNames
|
|
52
|
+
.split(",")
|
|
53
|
+
.map((s) => s.trim())
|
|
54
|
+
.filter(Boolean);
|
|
55
|
+
if (names.length === 0) {
|
|
56
|
+
return { results: [] };
|
|
57
|
+
}
|
|
58
|
+
const key = getObjectInfoBatchCacheKey(objectApiNames);
|
|
59
|
+
const cached = objectInfoBatchCache.get(key);
|
|
60
|
+
if (cached) return Promise.resolve(cached);
|
|
61
|
+
const inFlight = objectInfoBatchInFlight.get(key);
|
|
62
|
+
if (inFlight) return inFlight;
|
|
63
|
+
const promise = (async () => {
|
|
64
|
+
try {
|
|
65
|
+
const response = await getObjectInfosGraphQL(names, { signal });
|
|
66
|
+
const nodes = response?.uiapi?.objectInfos ?? [];
|
|
67
|
+
const result = graphQLObjectInfosToBatchResponse(nodes, names);
|
|
68
|
+
objectInfoBatchCache.set(key, result);
|
|
69
|
+
return result;
|
|
70
|
+
} finally {
|
|
71
|
+
objectInfoBatchInFlight.delete(key);
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
objectInfoBatchInFlight.set(key, promise);
|
|
75
|
+
return promise;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Fetches list filters for a specific object.
|
|
80
|
+
* Salesforce Search supports "Search Filters" (refinements) which are configured per object.
|
|
81
|
+
* This API returns the available filters (e.g., "Close Date", "Stage") that the user
|
|
82
|
+
* can use to narrow down the search results.
|
|
83
|
+
* @param objectApiName - The API name of the object (e.g., "Account")
|
|
84
|
+
* @param signal - Optional AbortSignal to cancel the request
|
|
85
|
+
* @returns Promise resolving to the search filters array
|
|
86
|
+
*/
|
|
87
|
+
export async function getObjectListFilters(
|
|
88
|
+
objectApiName: string,
|
|
89
|
+
signal?: AbortSignal,
|
|
90
|
+
): Promise<Filter[]> {
|
|
91
|
+
return fetchAndValidate(
|
|
92
|
+
(abortSignal) =>
|
|
93
|
+
uiApiClient.get(`/search-info/${safeEncodePath(objectApiName)}/filters`, {
|
|
94
|
+
signal: abortSignal,
|
|
95
|
+
}),
|
|
96
|
+
{
|
|
97
|
+
schema: FilterArraySchema,
|
|
98
|
+
errorContext: `filters for ${objectApiName}`,
|
|
99
|
+
extractData: (data: unknown) => {
|
|
100
|
+
if (!data) return [];
|
|
101
|
+
return Array.isArray(data) ? data : (data as { filters?: unknown }).filters || [];
|
|
102
|
+
},
|
|
103
|
+
signal,
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Fetches picklist values for a specific field via GraphQL (uiapi.objectInfos with objectInfoInputs).
|
|
110
|
+
*
|
|
111
|
+
* @param objectApiName - The API name of the object (e.g., "Account")
|
|
112
|
+
* @param fieldName - The API name of the field (e.g., "Type")
|
|
113
|
+
* @param recordTypeId - Optional record type ID (defaults to "012000000000000AAA" which is the default/master record type)
|
|
114
|
+
* @param signal - Optional AbortSignal to cancel the request
|
|
115
|
+
* @returns Promise resolving to an array of picklist values
|
|
116
|
+
*/
|
|
117
|
+
export async function getPicklistValues(
|
|
118
|
+
objectApiName: string,
|
|
119
|
+
fieldName: string,
|
|
120
|
+
recordTypeId: string = "012000000000000AAA",
|
|
121
|
+
signal?: AbortSignal,
|
|
122
|
+
): Promise<PicklistValue[]> {
|
|
123
|
+
const response = await getObjectInfosGraphQL([objectApiName], {
|
|
124
|
+
objectInfoInputs: [
|
|
125
|
+
{
|
|
126
|
+
apiName: objectApiName,
|
|
127
|
+
fieldNames: [fieldName],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
signal,
|
|
131
|
+
});
|
|
132
|
+
const nodes = response?.uiapi?.objectInfos ?? [];
|
|
133
|
+
const node = nodes[0];
|
|
134
|
+
if (!node) return [];
|
|
135
|
+
return extractPicklistValuesFromGraphQLObjectInfo(node, fieldName, recordTypeId);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Zod Schema for Search Parameters
|
|
139
|
+
const SearchParamsSchema = z.object({
|
|
140
|
+
filters: FilterCriteriaArraySchema.optional(),
|
|
141
|
+
pageSize: z.number().optional(),
|
|
142
|
+
pageToken: z.string().optional(),
|
|
143
|
+
sortBy: z.string().optional(),
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Search parameters for keyword search
|
|
148
|
+
*/
|
|
149
|
+
export type SearchParams = z.infer<typeof SearchParamsSchema>;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Performs a keyword search on a specific object.
|
|
153
|
+
* Returns records that match the text query along with pagination information.
|
|
154
|
+
*
|
|
155
|
+
* @param query - The search query string
|
|
156
|
+
* @param objectApiName - The API name of the object to search (e.g., "Account")
|
|
157
|
+
* @param params - Optional search parameters (pageSize, pageToken, filters, sortBy)
|
|
158
|
+
* @param signal - Optional AbortSignal to cancel the request
|
|
159
|
+
* @returns Promise resolving to the keyword search result with records and pagination tokens
|
|
160
|
+
*/
|
|
161
|
+
export async function searchResults(
|
|
162
|
+
query: string,
|
|
163
|
+
objectApiName: string,
|
|
164
|
+
params?: SearchParams,
|
|
165
|
+
signal?: AbortSignal,
|
|
166
|
+
): Promise<KeywordSearchResult> {
|
|
167
|
+
const searchParams = new URLSearchParams({
|
|
168
|
+
q: query,
|
|
169
|
+
objectApiName: objectApiName,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const body = {
|
|
173
|
+
filters: params?.filters ?? [],
|
|
174
|
+
pageSize: params?.pageSize ?? 50,
|
|
175
|
+
pageToken: params?.pageToken ?? "0",
|
|
176
|
+
sortBy: params?.sortBy ?? "",
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const response = await fetchAndValidate<SearchResultsResponse>(
|
|
180
|
+
(abortSignal) =>
|
|
181
|
+
uiApiClient.post(`/search/results/keyword?${searchParams.toString()}`, body, {
|
|
182
|
+
signal: abortSignal,
|
|
183
|
+
}),
|
|
184
|
+
{
|
|
185
|
+
schema: SearchResultsResponseSchema,
|
|
186
|
+
errorContext: `search results for ${objectApiName} with query "${query}"`,
|
|
187
|
+
signal,
|
|
188
|
+
},
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
return response.keywordSearchResult;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export const objectInfoService = {
|
|
195
|
+
getObjectInfoBatch,
|
|
196
|
+
getObjectListFilters,
|
|
197
|
+
getPicklistValues,
|
|
198
|
+
searchResults,
|
|
199
|
+
};
|