@apvee/spfx-react-toolkit 1.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/LICENSE +21 -0
- package/README.md +2012 -0
- package/lib/core/atoms.internal.d.ts +53 -0
- package/lib/core/atoms.internal.d.ts.map +1 -0
- package/lib/core/atoms.internal.js +35 -0
- package/lib/core/atoms.internal.js.map +1 -0
- package/lib/core/context.internal.d.ts +23 -0
- package/lib/core/context.internal.d.ts.map +1 -0
- package/lib/core/context.internal.js +34 -0
- package/lib/core/context.internal.js.map +1 -0
- package/lib/core/index.d.ts +6 -0
- package/lib/core/index.d.ts.map +1 -0
- package/lib/core/index.js +6 -0
- package/lib/core/index.js.map +1 -0
- package/lib/core/provider-application-customizer.d.ts +57 -0
- package/lib/core/provider-application-customizer.d.ts.map +1 -0
- package/lib/core/provider-application-customizer.js +45 -0
- package/lib/core/provider-application-customizer.js.map +1 -0
- package/lib/core/provider-base.internal.d.ts +20 -0
- package/lib/core/provider-base.internal.d.ts.map +1 -0
- package/lib/core/provider-base.internal.js +126 -0
- package/lib/core/provider-base.internal.js.map +1 -0
- package/lib/core/provider-field-customizer.d.ts +58 -0
- package/lib/core/provider-field-customizer.d.ts.map +1 -0
- package/lib/core/provider-field-customizer.js +46 -0
- package/lib/core/provider-field-customizer.js.map +1 -0
- package/lib/core/provider-listview-commandset.d.ts +60 -0
- package/lib/core/provider-listview-commandset.d.ts.map +1 -0
- package/lib/core/provider-listview-commandset.js +48 -0
- package/lib/core/provider-listview-commandset.js.map +1 -0
- package/lib/core/provider-webpart.d.ts +48 -0
- package/lib/core/provider-webpart.d.ts.map +1 -0
- package/lib/core/provider-webpart.js +36 -0
- package/lib/core/provider-webpart.js.map +1 -0
- package/lib/core/types.d.ts +84 -0
- package/lib/core/types.d.ts.map +1 -0
- package/lib/core/types.js +4 -0
- package/lib/core/types.js.map +1 -0
- package/lib/hooks/index.d.ts +34 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +34 -0
- package/lib/hooks/index.js.map +1 -0
- package/lib/hooks/useSPFxAadHttpClient.d.ts +231 -0
- package/lib/hooks/useSPFxAadHttpClient.d.ts.map +1 -0
- package/lib/hooks/useSPFxAadHttpClient.js +299 -0
- package/lib/hooks/useSPFxAadHttpClient.js.map +1 -0
- package/lib/hooks/useSPFxContainerInfo.d.ts +41 -0
- package/lib/hooks/useSPFxContainerInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxContainerInfo.js +47 -0
- package/lib/hooks/useSPFxContainerInfo.js.map +1 -0
- package/lib/hooks/useSPFxContainerSize.d.ts +119 -0
- package/lib/hooks/useSPFxContainerSize.d.ts.map +1 -0
- package/lib/hooks/useSPFxContainerSize.js +150 -0
- package/lib/hooks/useSPFxContainerSize.js.map +1 -0
- package/lib/hooks/useSPFxContext.d.ts +14 -0
- package/lib/hooks/useSPFxContext.d.ts.map +1 -0
- package/lib/hooks/useSPFxContext.js +16 -0
- package/lib/hooks/useSPFxContext.js.map +1 -0
- package/lib/hooks/useSPFxCorrelationInfo.d.ts +51 -0
- package/lib/hooks/useSPFxCorrelationInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxCorrelationInfo.js +58 -0
- package/lib/hooks/useSPFxCorrelationInfo.js.map +1 -0
- package/lib/hooks/useSPFxCrossSitePermissions.d.ts +81 -0
- package/lib/hooks/useSPFxCrossSitePermissions.d.ts.map +1 -0
- package/lib/hooks/useSPFxCrossSitePermissions.js +132 -0
- package/lib/hooks/useSPFxCrossSitePermissions.js.map +1 -0
- package/lib/hooks/useSPFxDisplayMode.d.ts +61 -0
- package/lib/hooks/useSPFxDisplayMode.d.ts.map +1 -0
- package/lib/hooks/useSPFxDisplayMode.js +69 -0
- package/lib/hooks/useSPFxDisplayMode.js.map +1 -0
- package/lib/hooks/useSPFxEnvironmentInfo.d.ts +63 -0
- package/lib/hooks/useSPFxEnvironmentInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxEnvironmentInfo.js +91 -0
- package/lib/hooks/useSPFxEnvironmentInfo.js.map +1 -0
- package/lib/hooks/useSPFxFluent9ThemeInfo.d.ts +105 -0
- package/lib/hooks/useSPFxFluent9ThemeInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxFluent9ThemeInfo.js +136 -0
- package/lib/hooks/useSPFxFluent9ThemeInfo.js.map +1 -0
- package/lib/hooks/useSPFxHubSiteInfo.d.ts +80 -0
- package/lib/hooks/useSPFxHubSiteInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxHubSiteInfo.js +127 -0
- package/lib/hooks/useSPFxHubSiteInfo.js.map +1 -0
- package/lib/hooks/useSPFxInstanceInfo.d.ts +41 -0
- package/lib/hooks/useSPFxInstanceInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxInstanceInfo.js +40 -0
- package/lib/hooks/useSPFxInstanceInfo.js.map +1 -0
- package/lib/hooks/useSPFxListInfo.d.ts +64 -0
- package/lib/hooks/useSPFxListInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxListInfo.js +70 -0
- package/lib/hooks/useSPFxListInfo.js.map +1 -0
- package/lib/hooks/useSPFxLocaleInfo.d.ts +123 -0
- package/lib/hooks/useSPFxLocaleInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxLocaleInfo.js +109 -0
- package/lib/hooks/useSPFxLocaleInfo.js.map +1 -0
- package/lib/hooks/useSPFxLogger.d.ts +108 -0
- package/lib/hooks/useSPFxLogger.d.ts.map +1 -0
- package/lib/hooks/useSPFxLogger.js +117 -0
- package/lib/hooks/useSPFxLogger.js.map +1 -0
- package/lib/hooks/useSPFxMSGraphClient.d.ts +200 -0
- package/lib/hooks/useSPFxMSGraphClient.d.ts.map +1 -0
- package/lib/hooks/useSPFxMSGraphClient.js +264 -0
- package/lib/hooks/useSPFxMSGraphClient.js.map +1 -0
- package/lib/hooks/useSPFxOneDriveAppData.d.ts +264 -0
- package/lib/hooks/useSPFxOneDriveAppData.d.ts.map +1 -0
- package/lib/hooks/useSPFxOneDriveAppData.js +395 -0
- package/lib/hooks/useSPFxOneDriveAppData.js.map +1 -0
- package/lib/hooks/useSPFxPageContext.d.ts +37 -0
- package/lib/hooks/useSPFxPageContext.d.ts.map +1 -0
- package/lib/hooks/useSPFxPageContext.js +49 -0
- package/lib/hooks/useSPFxPageContext.js.map +1 -0
- package/lib/hooks/useSPFxPageType.d.ts +82 -0
- package/lib/hooks/useSPFxPageType.d.ts.map +1 -0
- package/lib/hooks/useSPFxPageType.js +137 -0
- package/lib/hooks/useSPFxPageType.js.map +1 -0
- package/lib/hooks/useSPFxPerformance.d.ts +72 -0
- package/lib/hooks/useSPFxPerformance.d.ts.map +1 -0
- package/lib/hooks/useSPFxPerformance.js +167 -0
- package/lib/hooks/useSPFxPerformance.js.map +1 -0
- package/lib/hooks/useSPFxPermissions.d.ts +61 -0
- package/lib/hooks/useSPFxPermissions.d.ts.map +1 -0
- package/lib/hooks/useSPFxPermissions.js +73 -0
- package/lib/hooks/useSPFxPermissions.js.map +1 -0
- package/lib/hooks/useSPFxPnP.d.ts +539 -0
- package/lib/hooks/useSPFxPnP.d.ts.map +1 -0
- package/lib/hooks/useSPFxPnP.js +533 -0
- package/lib/hooks/useSPFxPnP.js.map +1 -0
- package/lib/hooks/useSPFxPnPContext.d.ts +290 -0
- package/lib/hooks/useSPFxPnPContext.d.ts.map +1 -0
- package/lib/hooks/useSPFxPnPContext.js +340 -0
- package/lib/hooks/useSPFxPnPContext.js.map +1 -0
- package/lib/hooks/useSPFxPnPList.d.ts +545 -0
- package/lib/hooks/useSPFxPnPList.d.ts.map +1 -0
- package/lib/hooks/useSPFxPnPList.js +906 -0
- package/lib/hooks/useSPFxPnPList.js.map +1 -0
- package/lib/hooks/useSPFxPnPSearch.d.ts +540 -0
- package/lib/hooks/useSPFxPnPSearch.d.ts.map +1 -0
- package/lib/hooks/useSPFxPnPSearch.js +672 -0
- package/lib/hooks/useSPFxPnPSearch.js.map +1 -0
- package/lib/hooks/useSPFxProperties.d.ts +80 -0
- package/lib/hooks/useSPFxProperties.d.ts.map +1 -0
- package/lib/hooks/useSPFxProperties.js +95 -0
- package/lib/hooks/useSPFxProperties.js.map +1 -0
- package/lib/hooks/useSPFxSPHttpClient.d.ts +218 -0
- package/lib/hooks/useSPFxSPHttpClient.d.ts.map +1 -0
- package/lib/hooks/useSPFxSPHttpClient.js +287 -0
- package/lib/hooks/useSPFxSPHttpClient.js.map +1 -0
- package/lib/hooks/useSPFxServiceScope.d.ts +107 -0
- package/lib/hooks/useSPFxServiceScope.d.ts.map +1 -0
- package/lib/hooks/useSPFxServiceScope.js +105 -0
- package/lib/hooks/useSPFxServiceScope.js.map +1 -0
- package/lib/hooks/useSPFxSiteInfo.d.ts +116 -0
- package/lib/hooks/useSPFxSiteInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxSiteInfo.js +109 -0
- package/lib/hooks/useSPFxSiteInfo.js.map +1 -0
- package/lib/hooks/useSPFxStorage.d.ts +81 -0
- package/lib/hooks/useSPFxStorage.d.ts.map +1 -0
- package/lib/hooks/useSPFxStorage.js +140 -0
- package/lib/hooks/useSPFxStorage.js.map +1 -0
- package/lib/hooks/useSPFxTeams.d.ts +63 -0
- package/lib/hooks/useSPFxTeams.d.ts.map +1 -0
- package/lib/hooks/useSPFxTeams.js +198 -0
- package/lib/hooks/useSPFxTeams.js.map +1 -0
- package/lib/hooks/useSPFxTenantProperty.d.ts +389 -0
- package/lib/hooks/useSPFxTenantProperty.d.ts.map +1 -0
- package/lib/hooks/useSPFxTenantProperty.js +683 -0
- package/lib/hooks/useSPFxTenantProperty.js.map +1 -0
- package/lib/hooks/useSPFxThemeInfo.d.ts +27 -0
- package/lib/hooks/useSPFxThemeInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxThemeInfo.js +33 -0
- package/lib/hooks/useSPFxThemeInfo.js.map +1 -0
- package/lib/hooks/useSPFxUserInfo.d.ts +47 -0
- package/lib/hooks/useSPFxUserInfo.d.ts.map +1 -0
- package/lib/hooks/useSPFxUserInfo.js +47 -0
- package/lib/hooks/useSPFxUserInfo.js.map +1 -0
- package/lib/hooks/useSPFxUserPhoto.d.ts +270 -0
- package/lib/hooks/useSPFxUserPhoto.d.ts.map +1 -0
- package/lib/hooks/useSPFxUserPhoto.js +346 -0
- package/lib/hooks/useSPFxUserPhoto.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +3 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/resize-observer.internal.d.ts +10 -0
- package/lib/utils/resize-observer.internal.d.ts.map +1 -0
- package/lib/utils/resize-observer.internal.js +34 -0
- package/lib/utils/resize-observer.internal.js.map +1 -0
- package/lib/utils/theme-subscription.internal.d.ts +11 -0
- package/lib/utils/theme-subscription.internal.d.ts.map +1 -0
- package/lib/utils/theme-subscription.internal.js +58 -0
- package/lib/utils/theme-subscription.internal.js.map +1 -0
- package/lib/utils/type-guards.internal.d.ts +35 -0
- package/lib/utils/type-guards.internal.d.ts.map +1 -0
- package/lib/utils/type-guards.internal.js +88 -0
- package/lib/utils/type-guards.internal.js.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.d.ts +13 -0
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.d.ts.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js +67 -0
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.manifest.json +21 -0
- package/lib/webparts/spFxReactToolkitTest/assets/welcome-dark.png +0 -0
- package/lib/webparts/spFxReactToolkitTest/assets/welcome-light.png +0 -0
- package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.d.ts +8 -0
- package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.d.ts.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.js +2 -0
- package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.js.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts +8 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js +1351 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.css +2 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.d.ts +18 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.d.ts.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js +19 -0
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js.map +1 -0
- package/lib/webparts/spFxReactToolkitTest/loc/en-us.js +16 -0
- package/package.json +95 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// useSPFxSPHttpClient.ts
|
|
2
|
+
// Hook to access SharePoint REST APIs with state management
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
13
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
14
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
15
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
16
|
+
function step(op) {
|
|
17
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
18
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
19
|
+
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;
|
|
20
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
21
|
+
switch (op[0]) {
|
|
22
|
+
case 0: case 1: t = op; break;
|
|
23
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
24
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
25
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
26
|
+
default:
|
|
27
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
28
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
29
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
30
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
31
|
+
if (t[2]) _.ops.pop();
|
|
32
|
+
_.trys.pop(); continue;
|
|
33
|
+
}
|
|
34
|
+
op = body.call(thisArg, _);
|
|
35
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
36
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
40
|
+
import { useSPFxContext } from './useSPFxContext';
|
|
41
|
+
/**
|
|
42
|
+
* Hook to access SharePoint REST APIs with built-in state management
|
|
43
|
+
*
|
|
44
|
+
* Provides native SPHttpClient for authenticated SharePoint REST API access.
|
|
45
|
+
* Offers two usage patterns:
|
|
46
|
+
*
|
|
47
|
+
* 1. **invoke()** - Automatic state management (loading + error tracking)
|
|
48
|
+
* 2. **client** - Direct access for full control
|
|
49
|
+
*
|
|
50
|
+
* For type safety, import SPFx types:
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import type { SPHttpClient } from '@microsoft/sp-http';
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Requirements:
|
|
56
|
+
* - SPHttpClient available in SPFx context
|
|
57
|
+
* - Appropriate SharePoint permissions for target APIs
|
|
58
|
+
*
|
|
59
|
+
* @param initialBaseUrl - Base URL for SharePoint site (optional, defaults to current site)
|
|
60
|
+
*
|
|
61
|
+
* @example Using invoke with state management
|
|
62
|
+
* ```tsx
|
|
63
|
+
* function WebInfo() {
|
|
64
|
+
* const { invoke, isLoading, error, clearError, baseUrl } = useSPFxSPHttpClient();
|
|
65
|
+
* const [webTitle, setWebTitle] = useState<string>('');
|
|
66
|
+
*
|
|
67
|
+
* const loadWeb = () => {
|
|
68
|
+
* invoke(client =>
|
|
69
|
+
* client.get(
|
|
70
|
+
* `${baseUrl}/_api/web?$select=Title`,
|
|
71
|
+
* SPHttpClient.configurations.v1
|
|
72
|
+
* ).then(res => res.json())
|
|
73
|
+
* ).then(web => setWebTitle(web.Title));
|
|
74
|
+
* };
|
|
75
|
+
*
|
|
76
|
+
* useEffect(() => { loadWeb(); }, []);
|
|
77
|
+
*
|
|
78
|
+
* if (isLoading) return <Spinner />;
|
|
79
|
+
* if (error) return (
|
|
80
|
+
* <MessageBar messageBarType={MessageBarType.error}>
|
|
81
|
+
* {error.message}
|
|
82
|
+
* <Link onClick={() => { clearError(); loadWeb(); }}>Retry</Link>
|
|
83
|
+
* </MessageBar>
|
|
84
|
+
* );
|
|
85
|
+
*
|
|
86
|
+
* return <h1>{webTitle}</h1>;
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @example Using client directly for advanced control
|
|
91
|
+
* ```tsx
|
|
92
|
+
* import type { SPHttpClient } from '@microsoft/sp-http';
|
|
93
|
+
*
|
|
94
|
+
* function ListItems() {
|
|
95
|
+
* const { client, baseUrl } = useSPFxSPHttpClient();
|
|
96
|
+
* const [items, setItems] = useState([]);
|
|
97
|
+
* const [loading, setLoading] = useState(false);
|
|
98
|
+
*
|
|
99
|
+
* if (!client) return <Spinner label="Initializing HTTP client..." />;
|
|
100
|
+
*
|
|
101
|
+
* const loadItems = async () => {
|
|
102
|
+
* setLoading(true);
|
|
103
|
+
* try {
|
|
104
|
+
* const response = await client.get(
|
|
105
|
+
* `${baseUrl}/_api/web/lists/getbytitle('Tasks')/items`,
|
|
106
|
+
* SPHttpClient.configurations.v1
|
|
107
|
+
* );
|
|
108
|
+
* const data = await response.json();
|
|
109
|
+
* setItems(data.value);
|
|
110
|
+
* } catch (err) {
|
|
111
|
+
* console.error(err);
|
|
112
|
+
* } finally {
|
|
113
|
+
* setLoading(false);
|
|
114
|
+
* }
|
|
115
|
+
* };
|
|
116
|
+
*
|
|
117
|
+
* return (
|
|
118
|
+
* <>
|
|
119
|
+
* <button onClick={loadItems} disabled={loading}>Load</button>
|
|
120
|
+
* {loading && <Spinner />}
|
|
121
|
+
* <DetailsList items={items} />
|
|
122
|
+
* </>
|
|
123
|
+
* );
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example CRUD operations with invoke
|
|
128
|
+
* ```tsx
|
|
129
|
+
* function TasksManager() {
|
|
130
|
+
* const { invoke, isLoading, error, baseUrl } = useSPFxSPHttpClient();
|
|
131
|
+
* const [tasks, setTasks] = useState([]);
|
|
132
|
+
*
|
|
133
|
+
* const loadTasks = () => {
|
|
134
|
+
* invoke(client =>
|
|
135
|
+
* client.get(
|
|
136
|
+
* `${baseUrl}/_api/web/lists/getbytitle('Tasks')/items`,
|
|
137
|
+
* SPHttpClient.configurations.v1
|
|
138
|
+
* ).then(res => res.json())
|
|
139
|
+
* ).then(data => setTasks(data.value));
|
|
140
|
+
* };
|
|
141
|
+
*
|
|
142
|
+
* const createTask = (title: string) => {
|
|
143
|
+
* invoke(client =>
|
|
144
|
+
* client.post(
|
|
145
|
+
* `${baseUrl}/_api/web/lists/getbytitle('Tasks')/items`,
|
|
146
|
+
* SPHttpClient.configurations.v1,
|
|
147
|
+
* { body: JSON.stringify({ Title: title }) }
|
|
148
|
+
* ).then(res => res.json())
|
|
149
|
+
* ).then(loadTasks);
|
|
150
|
+
* };
|
|
151
|
+
*
|
|
152
|
+
* const updateTask = (id: number, changes: any) => {
|
|
153
|
+
* invoke(client =>
|
|
154
|
+
* client.post(
|
|
155
|
+
* `${baseUrl}/_api/web/lists/getbytitle('Tasks')/items(${id})`,
|
|
156
|
+
* SPHttpClient.configurations.v1,
|
|
157
|
+
* {
|
|
158
|
+
* headers: { 'IF-MATCH': '*', 'X-HTTP-Method': 'MERGE' },
|
|
159
|
+
* body: JSON.stringify(changes)
|
|
160
|
+
* }
|
|
161
|
+
* )
|
|
162
|
+
* ).then(loadTasks);
|
|
163
|
+
* };
|
|
164
|
+
*
|
|
165
|
+
* const deleteTask = (id: number) => {
|
|
166
|
+
* invoke(client =>
|
|
167
|
+
* client.post(
|
|
168
|
+
* `${baseUrl}/_api/web/lists/getbytitle('Tasks')/items(${id})`,
|
|
169
|
+
* SPHttpClient.configurations.v1,
|
|
170
|
+
* {
|
|
171
|
+
* headers: { 'IF-MATCH': '*', 'X-HTTP-Method': 'DELETE' }
|
|
172
|
+
* }
|
|
173
|
+
* )
|
|
174
|
+
* ).then(loadTasks);
|
|
175
|
+
* };
|
|
176
|
+
*
|
|
177
|
+
* return (
|
|
178
|
+
* <TasksUI
|
|
179
|
+
* tasks={tasks}
|
|
180
|
+
* loading={isLoading}
|
|
181
|
+
* error={error}
|
|
182
|
+
* onCreate={createTask}
|
|
183
|
+
* onUpdate={updateTask}
|
|
184
|
+
* onDelete={deleteTask}
|
|
185
|
+
* />
|
|
186
|
+
* );
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @example Cross-site queries
|
|
191
|
+
* ```tsx
|
|
192
|
+
* function MultiSiteData() {
|
|
193
|
+
* const { invoke, setBaseUrl, baseUrl } = useSPFxSPHttpClient(
|
|
194
|
+
* 'https://contoso.sharepoint.com/sites/hr'
|
|
195
|
+
* );
|
|
196
|
+
*
|
|
197
|
+
* const switchToFinance = () => {
|
|
198
|
+
* setBaseUrl('https://contoso.sharepoint.com/sites/finance');
|
|
199
|
+
* };
|
|
200
|
+
*
|
|
201
|
+
* const loadLists = () => {
|
|
202
|
+
* invoke(client =>
|
|
203
|
+
* client.get(
|
|
204
|
+
* `${baseUrl}/_api/web/lists`,
|
|
205
|
+
* SPHttpClient.configurations.v1
|
|
206
|
+
* ).then(res => res.json())
|
|
207
|
+
* ).then(data => console.log(data.value));
|
|
208
|
+
* };
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export function useSPFxSPHttpClient(initialBaseUrl) {
|
|
213
|
+
var _this = this;
|
|
214
|
+
var _a, _b;
|
|
215
|
+
var spfxContext = useSPFxContext().spfxContext;
|
|
216
|
+
// Extract context data
|
|
217
|
+
var ctx = spfxContext;
|
|
218
|
+
// Default to current site if no baseUrl provided
|
|
219
|
+
var defaultBaseUrl = (initialBaseUrl === null || initialBaseUrl === void 0 ? void 0 : initialBaseUrl.trim()) || ((_b = (_a = ctx.pageContext) === null || _a === void 0 ? void 0 : _a.web) === null || _b === void 0 ? void 0 : _b.absoluteUrl) || '';
|
|
220
|
+
// Normalize: remove trailing slash for consistency (ES5-compatible)
|
|
221
|
+
var normalizedBaseUrl = defaultBaseUrl.charAt(defaultBaseUrl.length - 1) === '/'
|
|
222
|
+
? defaultBaseUrl.slice(0, -1)
|
|
223
|
+
: defaultBaseUrl;
|
|
224
|
+
// State management
|
|
225
|
+
var client = useState(ctx.spHttpClient)[0];
|
|
226
|
+
var _c = useState(normalizedBaseUrl), baseUrl = _c[0], setBaseUrlState = _c[1];
|
|
227
|
+
var _d = useState(false), isLoading = _d[0], setIsLoading = _d[1];
|
|
228
|
+
var _e = useState(undefined), error = _e[0], setError = _e[1];
|
|
229
|
+
// Initialize client
|
|
230
|
+
useEffect(function () {
|
|
231
|
+
if (!ctx.spHttpClient) {
|
|
232
|
+
console.warn('SPHttpClient not available in SPFx context');
|
|
233
|
+
}
|
|
234
|
+
}, [ctx.spHttpClient]);
|
|
235
|
+
// Public setter for baseUrl with normalization
|
|
236
|
+
var setBaseUrl = useCallback(function (url) {
|
|
237
|
+
var trimmed = url.trim();
|
|
238
|
+
var normalized = trimmed.charAt(trimmed.length - 1) === '/'
|
|
239
|
+
? trimmed.slice(0, -1)
|
|
240
|
+
: trimmed;
|
|
241
|
+
setBaseUrlState(normalized);
|
|
242
|
+
}, []);
|
|
243
|
+
// Invoke with automatic state management
|
|
244
|
+
var invoke = useCallback(function (fn) { return __awaiter(_this, void 0, void 0, function () {
|
|
245
|
+
var result, err_1, error_1;
|
|
246
|
+
return __generator(this, function (_a) {
|
|
247
|
+
switch (_a.label) {
|
|
248
|
+
case 0:
|
|
249
|
+
if (!client) {
|
|
250
|
+
throw new Error('SPHttpClient not initialized. Check SPFx context.');
|
|
251
|
+
}
|
|
252
|
+
setIsLoading(true);
|
|
253
|
+
setError(undefined);
|
|
254
|
+
_a.label = 1;
|
|
255
|
+
case 1:
|
|
256
|
+
_a.trys.push([1, 3, 4, 5]);
|
|
257
|
+
return [4 /*yield*/, fn(client)];
|
|
258
|
+
case 2:
|
|
259
|
+
result = _a.sent();
|
|
260
|
+
return [2 /*return*/, result];
|
|
261
|
+
case 3:
|
|
262
|
+
err_1 = _a.sent();
|
|
263
|
+
error_1 = err_1 instanceof Error ? err_1 : new Error(String(err_1));
|
|
264
|
+
setError(error_1);
|
|
265
|
+
throw error_1;
|
|
266
|
+
case 4:
|
|
267
|
+
setIsLoading(false);
|
|
268
|
+
return [7 /*endfinally*/];
|
|
269
|
+
case 5: return [2 /*return*/];
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}); }, [client]);
|
|
273
|
+
// Clear error helper
|
|
274
|
+
var clearError = useCallback(function () {
|
|
275
|
+
setError(undefined);
|
|
276
|
+
}, []);
|
|
277
|
+
return {
|
|
278
|
+
client: client,
|
|
279
|
+
invoke: invoke,
|
|
280
|
+
isLoading: isLoading,
|
|
281
|
+
error: error,
|
|
282
|
+
clearError: clearError,
|
|
283
|
+
setBaseUrl: setBaseUrl,
|
|
284
|
+
baseUrl: baseUrl,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=useSPFxSPHttpClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSPFxSPHttpClient.js","sourceRoot":"","sources":["../../src/hooks/useSPFxSPHttpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { ServiceScope, ServiceKey } from '@microsoft/sp-core-library';
|
|
2
|
+
/**
|
|
3
|
+
* Return type for useSPFxServiceScope hook
|
|
4
|
+
*/
|
|
5
|
+
export interface SPFxServiceScopeInfo {
|
|
6
|
+
/**
|
|
7
|
+
* Native ServiceScope instance from SPFx.
|
|
8
|
+
* Provides access to SPFx's dependency injection container.
|
|
9
|
+
*/
|
|
10
|
+
readonly serviceScope: ServiceScope | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Consume a service from the ServiceScope
|
|
13
|
+
*
|
|
14
|
+
* @param serviceKey - The service key to consume (from @microsoft/sp-core-library)
|
|
15
|
+
* @returns The service instance
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { ServiceKey } from '@microsoft/sp-core-library';
|
|
20
|
+
*
|
|
21
|
+
* const myService = consume<MyService>(MyService.serviceKey);
|
|
22
|
+
* myService.doSomething();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
readonly consume: <T>(serviceKey: ServiceKey<T>) => T;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Hook for SPFx ServiceScope (Dependency Injection)
|
|
29
|
+
*
|
|
30
|
+
* ServiceScope is SPFx's dependency injection container that provides:
|
|
31
|
+
* - Access to built-in SPFx services
|
|
32
|
+
* - Access to custom registered services
|
|
33
|
+
* - Service lifecycle management
|
|
34
|
+
* - Service isolation per scope
|
|
35
|
+
*
|
|
36
|
+
* Common built-in services available:
|
|
37
|
+
* - PageContext (via @microsoft/sp-page-context)
|
|
38
|
+
* - HttpClient (via @microsoft/sp-http)
|
|
39
|
+
* - MSGraphClientFactory (via @microsoft/sp-http)
|
|
40
|
+
* - SPPermission (via @microsoft/sp-page-context)
|
|
41
|
+
* - EventAggregator (via @microsoft/sp-core-library)
|
|
42
|
+
*
|
|
43
|
+
* Use this hook to:
|
|
44
|
+
* - Consume custom services registered in your solution
|
|
45
|
+
* - Access built-in SPFx services not exposed via context
|
|
46
|
+
* - Implement advanced service-based architectures
|
|
47
|
+
* - Create testable, decoupled components
|
|
48
|
+
*
|
|
49
|
+
* Note: Most common services (HttpClient, GraphClient, etc.)
|
|
50
|
+
* have dedicated hooks (useSPFxHttpClient, useSPFxGraphClient).
|
|
51
|
+
* Use this hook for custom services or advanced scenarios.
|
|
52
|
+
*
|
|
53
|
+
* @returns ServiceScope information and consume helper
|
|
54
|
+
*
|
|
55
|
+
* @example Consuming a custom service
|
|
56
|
+
* ```tsx
|
|
57
|
+
* import { ServiceKey } from '@microsoft/sp-core-library';
|
|
58
|
+
*
|
|
59
|
+
* // Define service interface
|
|
60
|
+
* interface IMyService {
|
|
61
|
+
* doSomething(): void;
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* // Service key (typically defined in service file)
|
|
65
|
+
* const MyServiceKey = ServiceKey.create<IMyService>('my-solution:IMyService', IMyService);
|
|
66
|
+
*
|
|
67
|
+
* function MyComponent() {
|
|
68
|
+
* const { consume } = useSPFxServiceScope();
|
|
69
|
+
*
|
|
70
|
+
* // Consume the service
|
|
71
|
+
* const myService = consume<IMyService>(MyServiceKey);
|
|
72
|
+
*
|
|
73
|
+
* const handleClick = () => {
|
|
74
|
+
* myService.doSomething();
|
|
75
|
+
* };
|
|
76
|
+
*
|
|
77
|
+
* return <button onClick={handleClick}>Do Something</button>;
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example Accessing EventAggregator
|
|
82
|
+
* ```tsx
|
|
83
|
+
* import { ServiceKey } from '@microsoft/sp-core-library';
|
|
84
|
+
* import { IEventAggregator } from '@microsoft/sp-core-library';
|
|
85
|
+
*
|
|
86
|
+
* function MyComponent() {
|
|
87
|
+
* const { serviceScope } = useSPFxServiceScope();
|
|
88
|
+
*
|
|
89
|
+
* useEffect(() => {
|
|
90
|
+
* // Access EventAggregator service
|
|
91
|
+
* const eventAggregator = serviceScope.consume(
|
|
92
|
+
* ServiceKey.create<IEventAggregator>('EventAggregator', IEventAggregator)
|
|
93
|
+
* );
|
|
94
|
+
*
|
|
95
|
+
* const subscription = eventAggregator.subscribe('MyEvent', (args) => {
|
|
96
|
+
* console.log('Event received:', args);
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* return () => subscription.dispose();
|
|
100
|
+
* }, [serviceScope]);
|
|
101
|
+
*
|
|
102
|
+
* return <div>Listening for events...</div>;
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export declare function useSPFxServiceScope(): SPFxServiceScopeInfo;
|
|
107
|
+
//# sourceMappingURL=useSPFxServiceScope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSPFxServiceScope.d.ts","sourceRoot":"","sources":["../../src/hooks/useSPFxServiceScope.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,SAAS,CAAC;IAEhD;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,wBAAgB,mBAAmB,IAAI,oBAAoB,CAwB1D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// useSPFxServiceScope.ts
|
|
2
|
+
// Hook for SPFx ServiceScope (Dependency Injection)
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import { useSPFxContext } from './useSPFxContext';
|
|
5
|
+
/**
|
|
6
|
+
* Hook for SPFx ServiceScope (Dependency Injection)
|
|
7
|
+
*
|
|
8
|
+
* ServiceScope is SPFx's dependency injection container that provides:
|
|
9
|
+
* - Access to built-in SPFx services
|
|
10
|
+
* - Access to custom registered services
|
|
11
|
+
* - Service lifecycle management
|
|
12
|
+
* - Service isolation per scope
|
|
13
|
+
*
|
|
14
|
+
* Common built-in services available:
|
|
15
|
+
* - PageContext (via @microsoft/sp-page-context)
|
|
16
|
+
* - HttpClient (via @microsoft/sp-http)
|
|
17
|
+
* - MSGraphClientFactory (via @microsoft/sp-http)
|
|
18
|
+
* - SPPermission (via @microsoft/sp-page-context)
|
|
19
|
+
* - EventAggregator (via @microsoft/sp-core-library)
|
|
20
|
+
*
|
|
21
|
+
* Use this hook to:
|
|
22
|
+
* - Consume custom services registered in your solution
|
|
23
|
+
* - Access built-in SPFx services not exposed via context
|
|
24
|
+
* - Implement advanced service-based architectures
|
|
25
|
+
* - Create testable, decoupled components
|
|
26
|
+
*
|
|
27
|
+
* Note: Most common services (HttpClient, GraphClient, etc.)
|
|
28
|
+
* have dedicated hooks (useSPFxHttpClient, useSPFxGraphClient).
|
|
29
|
+
* Use this hook for custom services or advanced scenarios.
|
|
30
|
+
*
|
|
31
|
+
* @returns ServiceScope information and consume helper
|
|
32
|
+
*
|
|
33
|
+
* @example Consuming a custom service
|
|
34
|
+
* ```tsx
|
|
35
|
+
* import { ServiceKey } from '@microsoft/sp-core-library';
|
|
36
|
+
*
|
|
37
|
+
* // Define service interface
|
|
38
|
+
* interface IMyService {
|
|
39
|
+
* doSomething(): void;
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* // Service key (typically defined in service file)
|
|
43
|
+
* const MyServiceKey = ServiceKey.create<IMyService>('my-solution:IMyService', IMyService);
|
|
44
|
+
*
|
|
45
|
+
* function MyComponent() {
|
|
46
|
+
* const { consume } = useSPFxServiceScope();
|
|
47
|
+
*
|
|
48
|
+
* // Consume the service
|
|
49
|
+
* const myService = consume<IMyService>(MyServiceKey);
|
|
50
|
+
*
|
|
51
|
+
* const handleClick = () => {
|
|
52
|
+
* myService.doSomething();
|
|
53
|
+
* };
|
|
54
|
+
*
|
|
55
|
+
* return <button onClick={handleClick}>Do Something</button>;
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Accessing EventAggregator
|
|
60
|
+
* ```tsx
|
|
61
|
+
* import { ServiceKey } from '@microsoft/sp-core-library';
|
|
62
|
+
* import { IEventAggregator } from '@microsoft/sp-core-library';
|
|
63
|
+
*
|
|
64
|
+
* function MyComponent() {
|
|
65
|
+
* const { serviceScope } = useSPFxServiceScope();
|
|
66
|
+
*
|
|
67
|
+
* useEffect(() => {
|
|
68
|
+
* // Access EventAggregator service
|
|
69
|
+
* const eventAggregator = serviceScope.consume(
|
|
70
|
+
* ServiceKey.create<IEventAggregator>('EventAggregator', IEventAggregator)
|
|
71
|
+
* );
|
|
72
|
+
*
|
|
73
|
+
* const subscription = eventAggregator.subscribe('MyEvent', (args) => {
|
|
74
|
+
* console.log('Event received:', args);
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* return () => subscription.dispose();
|
|
78
|
+
* }, [serviceScope]);
|
|
79
|
+
*
|
|
80
|
+
* return <div>Listening for events...</div>;
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function useSPFxServiceScope() {
|
|
85
|
+
var spfxContext = useSPFxContext().spfxContext;
|
|
86
|
+
// Extract serviceScope from context with native type
|
|
87
|
+
var ctx = spfxContext;
|
|
88
|
+
var serviceScope = ctx.serviceScope;
|
|
89
|
+
/**
|
|
90
|
+
* Helper to consume a service from the ServiceScope
|
|
91
|
+
* Wraps the serviceScope.consume() method with type safety
|
|
92
|
+
*/
|
|
93
|
+
var consume = useCallback(function (serviceKey) {
|
|
94
|
+
if (!serviceScope) {
|
|
95
|
+
throw new Error('ServiceScope is not available in SPFx context');
|
|
96
|
+
}
|
|
97
|
+
// Use native ServiceScope.consume() directly
|
|
98
|
+
return serviceScope.consume(serviceKey);
|
|
99
|
+
}, [serviceScope]);
|
|
100
|
+
return {
|
|
101
|
+
serviceScope: serviceScope,
|
|
102
|
+
consume: consume,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=useSPFxServiceScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSPFxServiceScope.js","sourceRoot":"","sources":["../../src/hooks/useSPFxServiceScope.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,oDAAoD;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA8BlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,MAAM,UAAU,mBAAmB;IACzB,IAAA,WAAW,GAAK,cAAc,EAAE,YAArB,CAAsB;IAEzC,qDAAqD;IACrD,IAAM,GAAG,GAAG,WAA8C,CAAC;IAC3D,IAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;IAEtC;;;OAGG;IACH,IAAM,OAAO,GAAG,WAAW,CAAC,UAAK,UAAyB;QACxD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,6CAA6C;QAC7C,OAAO,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,OAAO;QACL,YAAY,cAAA;QACZ,OAAO,SAAA;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Microsoft 365 Group information for group-connected sites
|
|
3
|
+
*/
|
|
4
|
+
export interface SPFxGroupInfo {
|
|
5
|
+
/** Group ID (GUID) */
|
|
6
|
+
readonly id: string;
|
|
7
|
+
/** Whether group is public (true) or private (false) */
|
|
8
|
+
readonly isPublic: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Return type for useSPFxSiteInfo hook
|
|
12
|
+
*/
|
|
13
|
+
export interface SPFxSiteInfo {
|
|
14
|
+
/** Web ID (GUID) */
|
|
15
|
+
readonly webId: string;
|
|
16
|
+
/** Web absolute URL */
|
|
17
|
+
readonly webUrl: string;
|
|
18
|
+
/** Web server relative URL */
|
|
19
|
+
readonly webServerRelativeUrl: string;
|
|
20
|
+
/** Web title */
|
|
21
|
+
readonly title: string;
|
|
22
|
+
/** Web language ID (LCID) */
|
|
23
|
+
readonly languageId: number;
|
|
24
|
+
/** Site logo URL (if configured) */
|
|
25
|
+
readonly logoUrl?: string;
|
|
26
|
+
/** Site collection ID (GUID) */
|
|
27
|
+
readonly siteId: string;
|
|
28
|
+
/** Site collection absolute URL */
|
|
29
|
+
readonly siteUrl: string;
|
|
30
|
+
/** Site collection server relative URL */
|
|
31
|
+
readonly siteServerRelativeUrl: string;
|
|
32
|
+
/** Site classification (e.g., "Confidential", "Public") */
|
|
33
|
+
readonly siteClassification?: string;
|
|
34
|
+
/** Microsoft 365 Group information (if group-connected) */
|
|
35
|
+
readonly siteGroup?: SPFxGroupInfo;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Hook to access site collection and web information
|
|
39
|
+
*
|
|
40
|
+
* Provides comprehensive information about the current SharePoint web (site/subsite)
|
|
41
|
+
* and parent site collection in a unified, flat structure.
|
|
42
|
+
*
|
|
43
|
+
* **Property naming pattern**:
|
|
44
|
+
* - **Identity properties** (id, url, serverRelativeUrl): Prefixed with `web` or `site` for clarity
|
|
45
|
+
* - **Web metadata** (title, languageId, logoUrl): No prefix (unique to web, most commonly used)
|
|
46
|
+
* - **Site properties**: All prefixed with `site` for consistency
|
|
47
|
+
*
|
|
48
|
+
* **Web properties** (primary context - 90% use case):
|
|
49
|
+
* - webId, webUrl, webServerRelativeUrl: Web identity
|
|
50
|
+
* - title: Web display name (most commonly used)
|
|
51
|
+
* - languageId: Web language (LCID)
|
|
52
|
+
* - logoUrl: Site logo URL (for branding)
|
|
53
|
+
*
|
|
54
|
+
* **Site collection properties** (parent context - 30-40% specialized):
|
|
55
|
+
* - siteId, siteUrl, siteServerRelativeUrl: Site collection identity
|
|
56
|
+
* - siteClassification: Enterprise classification label (e.g., "Confidential", "Public")
|
|
57
|
+
* - siteGroup: Microsoft 365 Group information (if group-connected)
|
|
58
|
+
*
|
|
59
|
+
* Note: In most cases (90%), you'll use web properties. Site collection properties
|
|
60
|
+
* are for specialized scenarios like subsites navigation, classification displays,
|
|
61
|
+
* or Microsoft 365 Group detection.
|
|
62
|
+
*
|
|
63
|
+
* @returns Site collection and web information
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* function MyComponent() {
|
|
68
|
+
* const {
|
|
69
|
+
* webUrl, // Web URL (identity)
|
|
70
|
+
* title, // Web title (most common)
|
|
71
|
+
* languageId, // Web language
|
|
72
|
+
* logoUrl, // Site logo (branding)
|
|
73
|
+
* siteClassification, // Site classification (enterprise)
|
|
74
|
+
* siteGroup // M365 Group info (if group-connected)
|
|
75
|
+
* } = useSPFxSiteInfo();
|
|
76
|
+
*
|
|
77
|
+
* return (
|
|
78
|
+
* <header>
|
|
79
|
+
* {logoUrl && <img src={logoUrl} alt="Site logo" />}
|
|
80
|
+
* <h1>{title}</h1>
|
|
81
|
+
* <a href={webUrl}>Visit Site</a>
|
|
82
|
+
*
|
|
83
|
+
* {siteClassification && (
|
|
84
|
+
* <Label>Classification: {siteClassification}</Label>
|
|
85
|
+
* )}
|
|
86
|
+
*
|
|
87
|
+
* {siteGroup && (
|
|
88
|
+
* <Badge>
|
|
89
|
+
* {siteGroup.isPublic ? 'Public Team' : 'Private Team'}
|
|
90
|
+
* </Badge>
|
|
91
|
+
* )}
|
|
92
|
+
*
|
|
93
|
+
* <p>Language ID: {languageId}</p>
|
|
94
|
+
* </header>
|
|
95
|
+
* );
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```tsx
|
|
101
|
+
* // Cross-site navigation (subsite scenario)
|
|
102
|
+
* function Navigation() {
|
|
103
|
+
* const { webUrl, siteUrl, title } = useSPFxSiteInfo();
|
|
104
|
+
*
|
|
105
|
+
* return (
|
|
106
|
+
* <nav>
|
|
107
|
+
* <a href={siteUrl}>Site Collection Home</a>
|
|
108
|
+
* <span> / </span>
|
|
109
|
+
* <a href={webUrl}>{title}</a>
|
|
110
|
+
* </nav>
|
|
111
|
+
* );
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export declare function useSPFxSiteInfo(): SPFxSiteInfo;
|
|
116
|
+
//# sourceMappingURL=useSPFxSiteInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSPFxSiteInfo.d.ts","sourceRoot":"","sources":["../../src/hooks/useSPFxSiteInfo.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAE3B,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,uBAAuB;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,8BAA8B;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IAGtC,gBAAgB;IAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,6BAA6B;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAG1B,gCAAgC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,mCAAmC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,0CAA0C;IAC1C,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAEvC,2DAA2D;IAC3D,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAErC,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6EG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAkC9C"}
|