@apvee/spfx-react-toolkit 1.2.1 → 2.0.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/lib/core/atoms.internal.js +1 -1
- package/lib/core/atoms.internal.js.map +1 -1
- package/lib/core/context.internal.js +2 -2
- package/lib/core/context.internal.js.map +1 -1
- package/lib/core/provider-base.internal.js +29 -29
- package/lib/core/provider-base.internal.js.map +1 -1
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.d.ts +14 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.d.ts.map +1 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js +20 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js.map +1 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.manifest.json +17 -0
- package/lib/extensions/spFxReactToolkitTest/loc/en-us.js +5 -0
- package/lib/hooks/index.d.ts +1 -0
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/index.js +1 -0
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/useAppCatalogUrl.internal.d.ts +26 -0
- package/lib/hooks/useAppCatalogUrl.internal.d.ts.map +1 -0
- package/lib/hooks/useAppCatalogUrl.internal.js +72 -0
- package/lib/hooks/useAppCatalogUrl.internal.js.map +1 -0
- package/lib/hooks/useAsyncInvoke.internal.js +27 -75
- package/lib/hooks/useAsyncInvoke.internal.js.map +1 -1
- package/lib/hooks/useSPFxAadHttpClient.d.ts +46 -0
- package/lib/hooks/useSPFxAadHttpClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxAadHttpClient.js +65 -20
- package/lib/hooks/useSPFxAadHttpClient.js.map +1 -1
- package/lib/hooks/useSPFxContainerInfo.js +5 -5
- package/lib/hooks/useSPFxContainerInfo.js.map +1 -1
- package/lib/hooks/useSPFxContainerSize.js +9 -10
- package/lib/hooks/useSPFxContainerSize.js.map +1 -1
- package/lib/hooks/useSPFxCorrelationInfo.js +6 -7
- package/lib/hooks/useSPFxCorrelationInfo.js.map +1 -1
- package/lib/hooks/useSPFxCrossSitePermissions.js +48 -58
- package/lib/hooks/useSPFxCrossSitePermissions.js.map +1 -1
- package/lib/hooks/useSPFxDisplayMode.js +8 -8
- package/lib/hooks/useSPFxDisplayMode.js.map +1 -1
- package/lib/hooks/useSPFxEnvironmentInfo.js +17 -18
- package/lib/hooks/useSPFxEnvironmentInfo.js.map +1 -1
- package/lib/hooks/useSPFxFluent9ThemeInfo.js +4 -4
- package/lib/hooks/useSPFxFluent9ThemeInfo.js.map +1 -1
- package/lib/hooks/useSPFxHttpClient.d.ts +18 -2
- package/lib/hooks/useSPFxHttpClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxHttpClient.js +19 -9
- package/lib/hooks/useSPFxHttpClient.js.map +1 -1
- package/lib/hooks/useSPFxHubSiteInfo.js +21 -24
- package/lib/hooks/useSPFxHubSiteInfo.js.map +1 -1
- package/lib/hooks/useSPFxInstanceInfo.js +2 -2
- package/lib/hooks/useSPFxInstanceInfo.js.map +1 -1
- package/lib/hooks/useSPFxListInfo.js +8 -9
- package/lib/hooks/useSPFxListInfo.js.map +1 -1
- package/lib/hooks/useSPFxLocaleInfo.js +10 -10
- package/lib/hooks/useSPFxLocaleInfo.js.map +1 -1
- package/lib/hooks/useSPFxLogger.js +26 -26
- package/lib/hooks/useSPFxLogger.js.map +1 -1
- package/lib/hooks/useSPFxMSGraphClient.d.ts +50 -3
- package/lib/hooks/useSPFxMSGraphClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxMSGraphClient.js +68 -15
- package/lib/hooks/useSPFxMSGraphClient.js.map +1 -1
- package/lib/hooks/useSPFxOneDriveAppData.d.ts +0 -1
- package/lib/hooks/useSPFxOneDriveAppData.d.ts.map +1 -1
- package/lib/hooks/useSPFxOneDriveAppData.js +420 -230
- package/lib/hooks/useSPFxOneDriveAppData.js.map +1 -1
- package/lib/hooks/useSPFxPageContext.js +2 -2
- package/lib/hooks/useSPFxPageContext.js.map +1 -1
- package/lib/hooks/useSPFxPageType.js +19 -20
- package/lib/hooks/useSPFxPageType.js.map +1 -1
- package/lib/hooks/useSPFxPerformance.js +33 -87
- package/lib/hooks/useSPFxPerformance.js.map +1 -1
- package/lib/hooks/useSPFxPermissions.js +14 -15
- package/lib/hooks/useSPFxPermissions.js.map +1 -1
- package/lib/hooks/useSPFxPnP.js +62 -119
- package/lib/hooks/useSPFxPnP.js.map +1 -1
- package/lib/hooks/useSPFxPnPContext.js +22 -25
- package/lib/hooks/useSPFxPnPContext.js.map +1 -1
- package/lib/hooks/useSPFxPnPList.js +307 -451
- package/lib/hooks/useSPFxPnPList.js.map +1 -1
- package/lib/hooks/useSPFxPnPSearch.js +262 -353
- package/lib/hooks/useSPFxPnPSearch.js.map +1 -1
- package/lib/hooks/useSPFxProperties.js +12 -20
- package/lib/hooks/useSPFxProperties.js.map +1 -1
- package/lib/hooks/useSPFxSPHttpClient.d.ts +18 -2
- package/lib/hooks/useSPFxSPHttpClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxSPHttpClient.js +28 -18
- package/lib/hooks/useSPFxSPHttpClient.js.map +1 -1
- package/lib/hooks/useSPFxServiceScope.js +6 -6
- package/lib/hooks/useSPFxServiceScope.js.map +1 -1
- package/lib/hooks/useSPFxSiteInfo.js +7 -8
- package/lib/hooks/useSPFxSiteInfo.js.map +1 -1
- package/lib/hooks/useSPFxStorage.js +22 -22
- package/lib/hooks/useSPFxStorage.js.map +1 -1
- package/lib/hooks/useSPFxTeams.js +37 -92
- package/lib/hooks/useSPFxTeams.js.map +1 -1
- package/lib/hooks/useSPFxTenantKeyValueStore.d.ts +252 -0
- package/lib/hooks/useSPFxTenantKeyValueStore.d.ts.map +1 -0
- package/lib/hooks/useSPFxTenantKeyValueStore.js +572 -0
- package/lib/hooks/useSPFxTenantKeyValueStore.js.map +1 -0
- package/lib/hooks/useSPFxTenantProperty.d.ts +23 -244
- package/lib/hooks/useSPFxTenantProperty.d.ts.map +1 -1
- package/lib/hooks/useSPFxTenantProperty.js +85 -559
- package/lib/hooks/useSPFxTenantProperty.js.map +1 -1
- package/lib/hooks/useSPFxUserInfo.js +3 -4
- package/lib/hooks/useSPFxUserInfo.js.map +1 -1
- package/lib/hooks/useSPFxUserPhoto.js +76 -123
- package/lib/hooks/useSPFxUserPhoto.js.map +1 -1
- package/lib/utils/resize-observer.internal.js +6 -7
- package/lib/utils/resize-observer.internal.js.map +1 -1
- package/lib/utils/theme-subscription.internal.js +8 -8
- package/lib/utils/theme-subscription.internal.js.map +1 -1
- package/lib/utils/type-guards.internal.js +6 -6
- package/lib/utils/type-guards.internal.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js +12 -37
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js +279 -342
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js +26 -86
- package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js +53 -113
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js +49 -121
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js +44 -103
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js +15 -15
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js +18 -66
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js +9 -9
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js +37 -86
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js +6 -9
- package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js +3 -6
- package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js.map +1 -1
- package/package.json +8 -6
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
-
function step(op) {
|
|
15
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
-
switch (op[0]) {
|
|
20
|
-
case 0: case 1: t = op; break;
|
|
21
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
-
default:
|
|
25
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
-
if (t[2]) _.ops.pop();
|
|
30
|
-
_.trys.pop(); continue;
|
|
31
|
-
}
|
|
32
|
-
op = body.call(thisArg, _);
|
|
33
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
1
|
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
38
2
|
import { useSPFxPnPContext } from './useSPFxPnPContext';
|
|
39
3
|
// Import PnPjs native search
|
|
@@ -53,7 +17,7 @@ import { SearchQueryBuilder } from '@pnp/sp/search';
|
|
|
53
17
|
* );
|
|
54
18
|
* ```
|
|
55
19
|
*/
|
|
56
|
-
export
|
|
20
|
+
export const SearchVerticals = {
|
|
57
21
|
/**
|
|
58
22
|
* All results (default) - no filtering
|
|
59
23
|
*/
|
|
@@ -308,364 +272,309 @@ export var SearchVerticals = {
|
|
|
308
272
|
* ```
|
|
309
273
|
*/
|
|
310
274
|
export function useSPFxPnPSearch(options, pnpContext) {
|
|
311
|
-
var _this = this;
|
|
312
|
-
var _a;
|
|
313
275
|
// Get PnP context
|
|
314
|
-
|
|
315
|
-
|
|
276
|
+
const context = useSPFxPnPContext(pnpContext?.siteUrl);
|
|
277
|
+
const { sp } = context;
|
|
316
278
|
// Default options
|
|
317
|
-
|
|
279
|
+
const defaultPageSize = options?.pageSize ?? 50;
|
|
318
280
|
// State
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
281
|
+
const [results, setResults] = useState([]);
|
|
282
|
+
const [totalResults, setTotalResults] = useState(0);
|
|
283
|
+
const [refiners, setRefiners] = useState([]);
|
|
284
|
+
const [loading, setLoading] = useState(false);
|
|
285
|
+
const [loadingMore, setLoadingMore] = useState(false);
|
|
286
|
+
const [error, setError] = useState(undefined);
|
|
287
|
+
const [hasMore, setHasMore] = useState(false);
|
|
326
288
|
// Tracking for pagination and refetch
|
|
327
289
|
// Type is wrapper function that returns the original callback (to avoid React state comparison issues)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
290
|
+
const [lastQueryBuilder, setLastQueryBuilder] = useState(null);
|
|
291
|
+
const [lastQueryText, setLastQueryText] = useState(null);
|
|
292
|
+
const [lastPageSize, setLastPageSize] = useState(undefined);
|
|
293
|
+
const [currentStartRow, setCurrentStartRow] = useState(0);
|
|
294
|
+
const [appliedRefiners, setAppliedRefiners] = useState(new Map());
|
|
333
295
|
// Refs
|
|
334
|
-
|
|
296
|
+
const mountedRef = useRef(true);
|
|
335
297
|
// Cleanup on unmount
|
|
336
|
-
useEffect(
|
|
298
|
+
useEffect(() => {
|
|
337
299
|
mountedRef.current = true;
|
|
338
300
|
return function cleanup() {
|
|
339
301
|
mountedRef.current = false;
|
|
340
302
|
};
|
|
341
303
|
}, []);
|
|
342
304
|
// Clear error handler
|
|
343
|
-
|
|
305
|
+
const clearError = useCallback(() => {
|
|
344
306
|
setError(undefined);
|
|
345
307
|
}, []);
|
|
346
308
|
/**
|
|
347
309
|
* Core search execution logic.
|
|
348
310
|
* Builds query with defaults, executes search, parses results.
|
|
349
311
|
*/
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
case
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
refinementFilters_1 = [];
|
|
392
|
-
refinersToApply.forEach(function (values, key) {
|
|
393
|
-
values.forEach(function (value) {
|
|
394
|
-
refinementFilters_1.push(key + ":equals('" + value + "')");
|
|
395
|
-
});
|
|
396
|
-
});
|
|
397
|
-
if (refinementFilters_1.length > 0) {
|
|
398
|
-
builder = builder.refinementFilters.apply(builder, refinementFilters_1);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
return [4 /*yield*/, sp.search(builder)];
|
|
402
|
-
case 2:
|
|
403
|
-
searchResults = _j.sent();
|
|
404
|
-
rawResults = (_c = searchResults.PrimarySearchResults) !== null && _c !== void 0 ? _c : [];
|
|
405
|
-
totalRows = (_d = searchResults.TotalRows) !== null && _d !== void 0 ? _d : 0;
|
|
406
|
-
parsedResults_1 = rawResults.map(function (result) {
|
|
407
|
-
var _a, _b;
|
|
408
|
-
// ISearchResult is already a flat object with all properties
|
|
409
|
-
// Generate ID from Path or DocId
|
|
410
|
-
var id = String((_b = (_a = result.DocId) !== null && _a !== void 0 ? _a : result.Path) !== null && _b !== void 0 ? _b : Math.random());
|
|
411
|
-
var rank = result.Rank ? parseInt(String(result.Rank), 10) : undefined;
|
|
412
|
-
return {
|
|
413
|
-
id: id,
|
|
414
|
-
data: result, // ISearchResult is already the data
|
|
415
|
-
raw: result, // Keep original for reference
|
|
416
|
-
rank: rank
|
|
417
|
-
};
|
|
312
|
+
const executeSearch = useCallback(async (query, queryOptions, startRow, appendResults, overrideRefiners) => {
|
|
313
|
+
if (!sp || !context?.isInitialized) {
|
|
314
|
+
const err = new Error('[useSPFxPnPSearch] PnP context not initialized. Ensure @pnp/sp/search is imported.');
|
|
315
|
+
setError(err);
|
|
316
|
+
throw err;
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const pageSize = queryOptions?.pageSize ?? lastPageSize ?? defaultPageSize;
|
|
320
|
+
const row = startRow ?? 0;
|
|
321
|
+
// Initialize SearchQueryBuilder
|
|
322
|
+
let builder;
|
|
323
|
+
if (typeof query === 'string') {
|
|
324
|
+
// String query case
|
|
325
|
+
builder = SearchQueryBuilder(query);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
// Builder callback case
|
|
329
|
+
builder = SearchQueryBuilder('');
|
|
330
|
+
// Apply default options BEFORE user callback
|
|
331
|
+
if (options?.selectProperties && options.selectProperties.length > 0) {
|
|
332
|
+
builder = builder.selectProperties(...options.selectProperties);
|
|
333
|
+
}
|
|
334
|
+
if (options?.refiners) {
|
|
335
|
+
builder = builder.refiners(options.refiners);
|
|
336
|
+
}
|
|
337
|
+
// Let user override everything
|
|
338
|
+
builder = query(builder);
|
|
339
|
+
}
|
|
340
|
+
// Apply pagination
|
|
341
|
+
builder = builder.rowLimit(pageSize);
|
|
342
|
+
if (row > 0) {
|
|
343
|
+
builder = builder.startRow(row);
|
|
344
|
+
}
|
|
345
|
+
// Apply refinement filters if any
|
|
346
|
+
// Use overrideRefiners if provided (for applyRefiner race condition fix)
|
|
347
|
+
const refinersToApply = overrideRefiners ?? appliedRefiners;
|
|
348
|
+
if (refinersToApply.size > 0) {
|
|
349
|
+
const refinementFilters = [];
|
|
350
|
+
refinersToApply.forEach(function (values, key) {
|
|
351
|
+
values.forEach(function (value) {
|
|
352
|
+
refinementFilters.push(key + ":equals('" + value + "')");
|
|
418
353
|
});
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
354
|
+
});
|
|
355
|
+
if (refinementFilters.length > 0) {
|
|
356
|
+
builder = builder.refinementFilters(...refinementFilters);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
// Execute search - sp.search() returns SearchResults (PnPjs v4)
|
|
360
|
+
// SearchResults exposes: ElapsedTime, RowCount, PrimarySearchResults, TotalRows
|
|
361
|
+
const searchResults = await sp.search(builder);
|
|
362
|
+
// PnPjs v4 SearchResults.PrimarySearchResults already contains parsed result objects
|
|
363
|
+
// Each result is an ISearchResult with properties like Title, Path, Rank, etc.
|
|
364
|
+
const rawResults = searchResults.PrimarySearchResults ?? [];
|
|
365
|
+
const totalRows = searchResults.TotalRows ?? 0;
|
|
366
|
+
// Map ISearchResult to our SearchResult<T> format
|
|
367
|
+
const parsedResults = rawResults.map(function (result) {
|
|
368
|
+
// ISearchResult is already a flat object with all properties
|
|
369
|
+
// Generate ID from Path or DocId
|
|
370
|
+
const id = String(result.DocId ?? result.Path ?? Math.random());
|
|
371
|
+
const rank = result.Rank ? parseInt(String(result.Rank), 10) : undefined;
|
|
372
|
+
return {
|
|
373
|
+
id: id,
|
|
374
|
+
data: result, // ISearchResult is already the data
|
|
375
|
+
raw: result, // Keep original for reference
|
|
376
|
+
rank: rank
|
|
377
|
+
};
|
|
378
|
+
});
|
|
379
|
+
// Parse refiners from RawSearchResults
|
|
380
|
+
// PnPjs v4: SearchResults.RawSearchResults.PrimaryQueryResult.RefinementResults.Refiners
|
|
381
|
+
const refinerResults = searchResults.RawSearchResults?.PrimaryQueryResult?.RefinementResults?.Refiners ?? [];
|
|
382
|
+
const parsedRefiners = refinerResults.map(function (refiner) {
|
|
383
|
+
return {
|
|
384
|
+
name: refiner.Name ?? '',
|
|
385
|
+
entries: (refiner.Entries ?? []).map(function (entry) {
|
|
422
386
|
return {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
return {
|
|
427
|
-
value: (_a = entry.RefinementName) !== null && _a !== void 0 ? _a : '',
|
|
428
|
-
count: parseInt(entry.RefinementCount, 10) || 0,
|
|
429
|
-
token: (_b = entry.RefinementToken) !== null && _b !== void 0 ? _b : ''
|
|
430
|
-
};
|
|
431
|
-
})
|
|
387
|
+
value: entry.RefinementName ?? '',
|
|
388
|
+
count: parseInt(entry.RefinementCount, 10) || 0,
|
|
389
|
+
token: entry.RefinementToken ?? ''
|
|
432
390
|
};
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (appendResults) {
|
|
440
|
-
setResults(function (prev) {
|
|
441
|
-
finalResultsLength_1 = prev.length + parsedResults_1.length;
|
|
442
|
-
return prev.concat(parsedResults_1);
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
finalResultsLength_1 = parsedResults_1.length;
|
|
447
|
-
setResults(parsedResults_1);
|
|
448
|
-
}
|
|
449
|
-
setTotalResults(totalRows);
|
|
450
|
-
setRefiners(parsedRefiners);
|
|
451
|
-
setHasMore(finalResultsLength_1 < totalRows);
|
|
452
|
-
return [2 /*return*/, parsedResults_1];
|
|
453
|
-
case 3:
|
|
454
|
-
err_1 = _j.sent();
|
|
455
|
-
error_1 = err_1 instanceof Error ? err_1 : new Error(String(err_1));
|
|
456
|
-
setError(error_1);
|
|
457
|
-
throw error_1;
|
|
458
|
-
case 4: return [2 /*return*/];
|
|
391
|
+
})
|
|
392
|
+
};
|
|
393
|
+
});
|
|
394
|
+
// Update state
|
|
395
|
+
if (!mountedRef.current) {
|
|
396
|
+
return parsedResults;
|
|
459
397
|
}
|
|
460
|
-
|
|
461
|
-
|
|
398
|
+
// Calculate new results length for hasMore using functional update
|
|
399
|
+
// This avoids needing results.length in the dependency array
|
|
400
|
+
let finalResultsLength = 0;
|
|
401
|
+
if (appendResults) {
|
|
402
|
+
setResults(function (prev) {
|
|
403
|
+
finalResultsLength = prev.length + parsedResults.length;
|
|
404
|
+
return prev.concat(parsedResults);
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
finalResultsLength = parsedResults.length;
|
|
409
|
+
setResults(parsedResults);
|
|
410
|
+
}
|
|
411
|
+
setTotalResults(totalRows);
|
|
412
|
+
setRefiners(parsedRefiners);
|
|
413
|
+
setHasMore(finalResultsLength < totalRows);
|
|
414
|
+
return parsedResults;
|
|
415
|
+
}
|
|
416
|
+
catch (err) {
|
|
417
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
418
|
+
setError(error);
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
}, [sp, context?.isInitialized, options, defaultPageSize, lastPageSize, appliedRefiners]);
|
|
462
422
|
/**
|
|
463
423
|
* Executes a search query.
|
|
464
424
|
*/
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
_b.label = 1;
|
|
476
|
-
case 1:
|
|
477
|
-
_b.trys.push([1, , 3, 4]);
|
|
478
|
-
// Store query for refetch/loadMore
|
|
479
|
-
if (typeof query === 'string') {
|
|
480
|
-
setLastQueryText(query);
|
|
481
|
-
setLastQueryBuilder(null);
|
|
482
|
-
}
|
|
483
|
-
else {
|
|
484
|
-
setLastQueryBuilder(function () { return query; });
|
|
485
|
-
setLastQueryText(null);
|
|
486
|
-
}
|
|
487
|
-
setLastPageSize((_a = queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.pageSize) !== null && _a !== void 0 ? _a : defaultPageSize);
|
|
488
|
-
return [4 /*yield*/, executeSearch(query, queryOptions, 0, false)];
|
|
489
|
-
case 2:
|
|
490
|
-
parsedResults = _b.sent();
|
|
491
|
-
return [2 /*return*/, parsedResults];
|
|
492
|
-
case 3:
|
|
493
|
-
if (mountedRef.current) {
|
|
494
|
-
setLoading(false);
|
|
495
|
-
}
|
|
496
|
-
return [7 /*endfinally*/];
|
|
497
|
-
case 4: return [2 /*return*/];
|
|
425
|
+
const search = useCallback(async (query, queryOptions) => {
|
|
426
|
+
setLoading(true);
|
|
427
|
+
setError(undefined);
|
|
428
|
+
setCurrentStartRow(0);
|
|
429
|
+
setAppliedRefiners(new Map()); // Reset refiners on new search
|
|
430
|
+
try {
|
|
431
|
+
// Store query for refetch/loadMore
|
|
432
|
+
if (typeof query === 'string') {
|
|
433
|
+
setLastQueryText(query);
|
|
434
|
+
setLastQueryBuilder(null);
|
|
498
435
|
}
|
|
499
|
-
|
|
500
|
-
|
|
436
|
+
else {
|
|
437
|
+
setLastQueryBuilder(function () { return query; });
|
|
438
|
+
setLastQueryText(null);
|
|
439
|
+
}
|
|
440
|
+
setLastPageSize(queryOptions?.pageSize ?? defaultPageSize);
|
|
441
|
+
const parsedResults = await executeSearch(query, queryOptions, 0, false);
|
|
442
|
+
return parsedResults;
|
|
443
|
+
}
|
|
444
|
+
finally {
|
|
445
|
+
if (mountedRef.current) {
|
|
446
|
+
setLoading(false);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}, [executeSearch, defaultPageSize]);
|
|
501
450
|
/**
|
|
502
451
|
* Gets search suggestions.
|
|
503
452
|
*/
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
result = _b.sent();
|
|
521
|
-
return [2 /*return*/, (_a = result.Queries) !== null && _a !== void 0 ? _a : []];
|
|
522
|
-
case 3:
|
|
523
|
-
err_2 = _b.sent();
|
|
524
|
-
error_2 = err_2 instanceof Error ? err_2 : new Error(String(err_2));
|
|
525
|
-
setError(error_2);
|
|
526
|
-
throw error_2;
|
|
527
|
-
case 4: return [2 /*return*/];
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
}); }, [sp, context === null || context === void 0 ? void 0 : context.isInitialized]);
|
|
453
|
+
const suggest = useCallback(async (queryText) => {
|
|
454
|
+
if (!sp || !context?.isInitialized) {
|
|
455
|
+
const err = new Error('[useSPFxPnPSearch] PnP context not initialized.');
|
|
456
|
+
setError(err);
|
|
457
|
+
throw err;
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
460
|
+
const result = await sp.searchSuggest(queryText);
|
|
461
|
+
return result.Queries ?? [];
|
|
462
|
+
}
|
|
463
|
+
catch (err) {
|
|
464
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
465
|
+
setError(error);
|
|
466
|
+
throw error;
|
|
467
|
+
}
|
|
468
|
+
}, [sp, context?.isInitialized]);
|
|
531
469
|
/**
|
|
532
470
|
* Loads more results (pagination).
|
|
533
471
|
*/
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
parsedResults = _a.sent();
|
|
562
|
-
setCurrentStartRow(nextStartRow);
|
|
563
|
-
return [2 /*return*/, parsedResults];
|
|
564
|
-
case 3:
|
|
565
|
-
if (mountedRef.current) {
|
|
566
|
-
setLoadingMore(false);
|
|
567
|
-
}
|
|
568
|
-
return [7 /*endfinally*/];
|
|
569
|
-
case 4: return [2 /*return*/];
|
|
472
|
+
const loadMore = useCallback(async () => {
|
|
473
|
+
if (!lastQueryBuilder && !lastQueryText) {
|
|
474
|
+
const err = new Error('[useSPFxPnPSearch] No previous search to load more from. Call search() first.');
|
|
475
|
+
setError(err);
|
|
476
|
+
throw err;
|
|
477
|
+
}
|
|
478
|
+
if (!lastPageSize) {
|
|
479
|
+
const err = new Error('[useSPFxPnPSearch] Cannot loadMore without pageSize. Specify pageSize in options or search call.');
|
|
480
|
+
setError(err);
|
|
481
|
+
throw err;
|
|
482
|
+
}
|
|
483
|
+
setLoadingMore(true);
|
|
484
|
+
setError(undefined);
|
|
485
|
+
try {
|
|
486
|
+
const nextStartRow = currentStartRow + lastPageSize;
|
|
487
|
+
// Call lastQueryBuilder() to get the original callback function
|
|
488
|
+
const query = lastQueryBuilder
|
|
489
|
+
? lastQueryBuilder()
|
|
490
|
+
: lastQueryText;
|
|
491
|
+
const parsedResults = await executeSearch(query, { pageSize: lastPageSize }, nextStartRow, true // Append results
|
|
492
|
+
);
|
|
493
|
+
setCurrentStartRow(nextStartRow);
|
|
494
|
+
return parsedResults;
|
|
495
|
+
}
|
|
496
|
+
finally {
|
|
497
|
+
if (mountedRef.current) {
|
|
498
|
+
setLoadingMore(false);
|
|
570
499
|
}
|
|
571
|
-
}
|
|
572
|
-
}
|
|
500
|
+
}
|
|
501
|
+
}, [lastQueryBuilder, lastQueryText, lastPageSize, currentStartRow, executeSearch]);
|
|
573
502
|
/**
|
|
574
503
|
* Re-executes the last search.
|
|
575
504
|
*/
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return [4 /*yield*/, executeSearch(query, { pageSize: lastPageSize }, 0, false)];
|
|
596
|
-
case 2:
|
|
597
|
-
_a.sent();
|
|
598
|
-
return [3 /*break*/, 4];
|
|
599
|
-
case 3:
|
|
600
|
-
if (mountedRef.current) {
|
|
601
|
-
setLoading(false);
|
|
602
|
-
}
|
|
603
|
-
return [7 /*endfinally*/];
|
|
604
|
-
case 4: return [2 /*return*/];
|
|
505
|
+
const refetch = useCallback(async () => {
|
|
506
|
+
if (!lastQueryBuilder && !lastQueryText) {
|
|
507
|
+
const err = new Error('[useSPFxPnPSearch] No previous search to refetch. Call search() first.');
|
|
508
|
+
setError(err);
|
|
509
|
+
throw err;
|
|
510
|
+
}
|
|
511
|
+
setLoading(true);
|
|
512
|
+
setError(undefined);
|
|
513
|
+
setCurrentStartRow(0);
|
|
514
|
+
try {
|
|
515
|
+
// Call lastQueryBuilder() to get the original callback function
|
|
516
|
+
const query = lastQueryBuilder
|
|
517
|
+
? lastQueryBuilder()
|
|
518
|
+
: lastQueryText;
|
|
519
|
+
await executeSearch(query, { pageSize: lastPageSize }, 0, false);
|
|
520
|
+
}
|
|
521
|
+
finally {
|
|
522
|
+
if (mountedRef.current) {
|
|
523
|
+
setLoading(false);
|
|
605
524
|
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
525
|
+
}
|
|
526
|
+
}, [lastQueryBuilder, lastQueryText, lastPageSize, executeSearch]);
|
|
608
527
|
/**
|
|
609
528
|
* Applies a refiner filter to the current search.
|
|
610
529
|
*/
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
newRefiners = new Map();
|
|
623
|
-
appliedRefiners.forEach(function (value, key) {
|
|
624
|
-
newRefiners.set(key, value);
|
|
625
|
-
});
|
|
626
|
-
existing = (_a = newRefiners.get(refinerName)) !== null && _a !== void 0 ? _a : [];
|
|
627
|
-
index = existing.indexOf(refinerValue);
|
|
628
|
-
if (index > -1) {
|
|
629
|
-
updated = existing.slice();
|
|
630
|
-
updated.splice(index, 1);
|
|
631
|
-
if (updated.length === 0) {
|
|
632
|
-
newRefiners.delete(refinerName);
|
|
633
|
-
}
|
|
634
|
-
else {
|
|
635
|
-
newRefiners.set(refinerName, updated);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
else {
|
|
639
|
-
newRefiners.set(refinerName, existing.concat([refinerValue]));
|
|
640
|
-
}
|
|
641
|
-
// Update state for UI
|
|
642
|
-
setAppliedRefiners(newRefiners);
|
|
643
|
-
// Re-execute search with new refiners passed directly
|
|
644
|
-
// This avoids the race condition where state isn't updated yet
|
|
645
|
-
setLoading(true);
|
|
646
|
-
setError(undefined);
|
|
647
|
-
setCurrentStartRow(0);
|
|
648
|
-
_b.label = 1;
|
|
649
|
-
case 1:
|
|
650
|
-
_b.trys.push([1, , 3, 4]);
|
|
651
|
-
query = lastQueryBuilder
|
|
652
|
-
? lastQueryBuilder()
|
|
653
|
-
: lastQueryText;
|
|
654
|
-
// Pass newRefiners directly to avoid race condition
|
|
655
|
-
return [4 /*yield*/, executeSearch(query, { pageSize: lastPageSize }, 0, false, newRefiners)];
|
|
656
|
-
case 2:
|
|
657
|
-
// Pass newRefiners directly to avoid race condition
|
|
658
|
-
_b.sent();
|
|
659
|
-
return [3 /*break*/, 4];
|
|
660
|
-
case 3:
|
|
661
|
-
if (mountedRef.current) {
|
|
662
|
-
setLoading(false);
|
|
663
|
-
}
|
|
664
|
-
return [7 /*endfinally*/];
|
|
665
|
-
case 4: return [2 /*return*/];
|
|
666
|
-
}
|
|
530
|
+
const applyRefiner = useCallback(async (refinerName, refinerValue) => {
|
|
531
|
+
if (!lastQueryBuilder && !lastQueryText) {
|
|
532
|
+
const err = new Error('[useSPFxPnPSearch] No previous search to apply refiner to. Call search() first.');
|
|
533
|
+
setError(err);
|
|
534
|
+
throw err;
|
|
535
|
+
}
|
|
536
|
+
// Calculate new refiners map (toggle logic)
|
|
537
|
+
const newRefiners = new Map();
|
|
538
|
+
appliedRefiners.forEach(function (value, key) {
|
|
539
|
+
newRefiners.set(key, value);
|
|
667
540
|
});
|
|
668
|
-
|
|
541
|
+
const existing = newRefiners.get(refinerName) ?? [];
|
|
542
|
+
// Toggle: if already exists, remove; otherwise add
|
|
543
|
+
const index = existing.indexOf(refinerValue);
|
|
544
|
+
if (index > -1) {
|
|
545
|
+
const updated = existing.slice();
|
|
546
|
+
updated.splice(index, 1);
|
|
547
|
+
if (updated.length === 0) {
|
|
548
|
+
newRefiners.delete(refinerName);
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
newRefiners.set(refinerName, updated);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
newRefiners.set(refinerName, existing.concat([refinerValue]));
|
|
556
|
+
}
|
|
557
|
+
// Update state for UI
|
|
558
|
+
setAppliedRefiners(newRefiners);
|
|
559
|
+
// Re-execute search with new refiners passed directly
|
|
560
|
+
// This avoids the race condition where state isn't updated yet
|
|
561
|
+
setLoading(true);
|
|
562
|
+
setError(undefined);
|
|
563
|
+
setCurrentStartRow(0);
|
|
564
|
+
try {
|
|
565
|
+
// Call lastQueryBuilder() to get the original callback function
|
|
566
|
+
const query = lastQueryBuilder
|
|
567
|
+
? lastQueryBuilder()
|
|
568
|
+
: lastQueryText;
|
|
569
|
+
// Pass newRefiners directly to avoid race condition
|
|
570
|
+
await executeSearch(query, { pageSize: lastPageSize }, 0, false, newRefiners);
|
|
571
|
+
}
|
|
572
|
+
finally {
|
|
573
|
+
if (mountedRef.current) {
|
|
574
|
+
setLoading(false);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}, [lastQueryBuilder, lastQueryText, lastPageSize, appliedRefiners, executeSearch]);
|
|
669
578
|
return {
|
|
670
579
|
search: search,
|
|
671
580
|
suggest: suggest,
|