@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,200 @@
|
|
|
1
|
+
import type { MSGraphClientV3 } from '@microsoft/sp-http';
|
|
2
|
+
/**
|
|
3
|
+
* Return type for useSPFxMSGraphClient hook
|
|
4
|
+
*/
|
|
5
|
+
export interface SPFxMSGraphClientInfo {
|
|
6
|
+
/**
|
|
7
|
+
* Native MSGraphClientV3 from SPFx.
|
|
8
|
+
* Provides access to Microsoft Graph API with built-in authentication.
|
|
9
|
+
*/
|
|
10
|
+
readonly client: MSGraphClientV3 | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Invoke Graph API call with automatic state management.
|
|
13
|
+
* Tracks loading state and captures errors automatically.
|
|
14
|
+
*
|
|
15
|
+
* @param fn - Function that receives Graph client and returns a promise
|
|
16
|
+
* @returns Promise with the result
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const { invoke } = useSPFxMSGraphClient();
|
|
21
|
+
*
|
|
22
|
+
* const user = await invoke(client =>
|
|
23
|
+
* client.api('/me').select('displayName,mail').get()
|
|
24
|
+
* );
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
readonly invoke: <T>(fn: (client: MSGraphClientV3) => Promise<T>) => Promise<T>;
|
|
28
|
+
/**
|
|
29
|
+
* Loading state - true during invoke() calls.
|
|
30
|
+
* Does not track direct client usage.
|
|
31
|
+
*/
|
|
32
|
+
readonly isLoading: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Last error from invoke() calls.
|
|
35
|
+
* Does not capture errors from direct client usage.
|
|
36
|
+
*/
|
|
37
|
+
readonly error: Error | undefined;
|
|
38
|
+
/** Clear the current error */
|
|
39
|
+
readonly clearError: () => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Hook to access Microsoft Graph client with built-in state management
|
|
43
|
+
*
|
|
44
|
+
* Provides native MSGraphClientV3 for authenticated Microsoft Graph 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, install @microsoft/microsoft-graph-types:
|
|
51
|
+
* ```bash
|
|
52
|
+
* npm install @microsoft/microsoft-graph-types --save-dev
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* And import SPFx types:
|
|
56
|
+
* ```typescript
|
|
57
|
+
* import type { MSGraphClientV3 } from '@microsoft/sp-http';
|
|
58
|
+
* import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Requirements:
|
|
62
|
+
* - MSGraphClientFactory available in SPFx context (v1.15.0+)
|
|
63
|
+
* - Appropriate Microsoft Graph permissions granted by admin
|
|
64
|
+
*
|
|
65
|
+
* @example Using invoke with state management
|
|
66
|
+
* ```tsx
|
|
67
|
+
* import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
|
|
68
|
+
*
|
|
69
|
+
* function UserProfile() {
|
|
70
|
+
* const { invoke, isLoading, error, clearError } = useSPFxMSGraphClient();
|
|
71
|
+
* const [user, setUser] = useState<MicrosoftGraph.User>();
|
|
72
|
+
*
|
|
73
|
+
* const loadUser = () => {
|
|
74
|
+
* invoke(client =>
|
|
75
|
+
* client.api('/me')
|
|
76
|
+
* .select('displayName,mail,jobTitle')
|
|
77
|
+
* .get()
|
|
78
|
+
* ).then(setUser);
|
|
79
|
+
* };
|
|
80
|
+
*
|
|
81
|
+
* useEffect(() => { loadUser(); }, []);
|
|
82
|
+
*
|
|
83
|
+
* if (isLoading) return <Spinner />;
|
|
84
|
+
* if (error) return (
|
|
85
|
+
* <MessageBar messageBarType={MessageBarType.error}>
|
|
86
|
+
* {error.message}
|
|
87
|
+
* <Link onClick={() => { clearError(); loadUser(); }}>Retry</Link>
|
|
88
|
+
* </MessageBar>
|
|
89
|
+
* );
|
|
90
|
+
*
|
|
91
|
+
* return <div>{user?.displayName}</div>;
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @example Using client directly for advanced control
|
|
96
|
+
* ```tsx
|
|
97
|
+
* import type { MSGraphClientV3 } from '@microsoft/sp-http';
|
|
98
|
+
* import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
|
|
99
|
+
*
|
|
100
|
+
* function MessagesList() {
|
|
101
|
+
* const { client } = useSPFxMSGraphClient();
|
|
102
|
+
* const [messages, setMessages] = useState<MicrosoftGraph.Message[]>([]);
|
|
103
|
+
* const [loading, setLoading] = useState(false);
|
|
104
|
+
*
|
|
105
|
+
* if (!client) return <Spinner label="Initializing Graph client..." />;
|
|
106
|
+
*
|
|
107
|
+
* const loadMessages = async () => {
|
|
108
|
+
* setLoading(true);
|
|
109
|
+
* try {
|
|
110
|
+
* const result = await client.api('/me/messages')
|
|
111
|
+
* .version('v1.0')
|
|
112
|
+
* .select('subject,from,receivedDateTime')
|
|
113
|
+
* .filter("importance eq 'high'")
|
|
114
|
+
* .orderBy('receivedDateTime DESC')
|
|
115
|
+
* .top(20)
|
|
116
|
+
* .get();
|
|
117
|
+
* setMessages(result.value);
|
|
118
|
+
* } catch (err) {
|
|
119
|
+
* console.error(err);
|
|
120
|
+
* } finally {
|
|
121
|
+
* setLoading(false);
|
|
122
|
+
* }
|
|
123
|
+
* };
|
|
124
|
+
*
|
|
125
|
+
* return (
|
|
126
|
+
* <>
|
|
127
|
+
* <button onClick={loadMessages} disabled={loading}>Load</button>
|
|
128
|
+
* {loading && <Spinner />}
|
|
129
|
+
* <MessageList items={messages} />
|
|
130
|
+
* </>
|
|
131
|
+
* );
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @example CRUD operations with invoke
|
|
136
|
+
* ```tsx
|
|
137
|
+
* function ContactsManager() {
|
|
138
|
+
* const { invoke, isLoading, error } = useSPFxMSGraphClient();
|
|
139
|
+
* const [contacts, setContacts] = useState([]);
|
|
140
|
+
*
|
|
141
|
+
* const loadContacts = () => {
|
|
142
|
+
* invoke(client =>
|
|
143
|
+
* client.api('/me/contacts').get()
|
|
144
|
+
* ).then(result => setContacts(result.value));
|
|
145
|
+
* };
|
|
146
|
+
*
|
|
147
|
+
* const createContact = (contact: any) => {
|
|
148
|
+
* invoke(client =>
|
|
149
|
+
* client.api('/me/contacts').post(contact)
|
|
150
|
+
* ).then(newContact => setContacts([...contacts, newContact]));
|
|
151
|
+
* };
|
|
152
|
+
*
|
|
153
|
+
* const updateContact = (id: string, changes: any) => {
|
|
154
|
+
* invoke(client =>
|
|
155
|
+
* client.api(`/me/contacts/${id}`).patch(changes)
|
|
156
|
+
* ).then(loadContacts);
|
|
157
|
+
* };
|
|
158
|
+
*
|
|
159
|
+
* const deleteContact = (id: string) => {
|
|
160
|
+
* invoke(client =>
|
|
161
|
+
* client.api(`/me/contacts/${id}`).delete()
|
|
162
|
+
* ).then(() => setContacts(contacts.filter(c => c.id !== id)));
|
|
163
|
+
* };
|
|
164
|
+
*
|
|
165
|
+
* return (
|
|
166
|
+
* <ContactsUI
|
|
167
|
+
* contacts={contacts}
|
|
168
|
+
* loading={isLoading}
|
|
169
|
+
* error={error}
|
|
170
|
+
* onCreate={createContact}
|
|
171
|
+
* onUpdate={updateContact}
|
|
172
|
+
* onDelete={deleteContact}
|
|
173
|
+
* />
|
|
174
|
+
* );
|
|
175
|
+
* }
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @example Batch operations with client
|
|
179
|
+
* ```tsx
|
|
180
|
+
* function BatchOperations() {
|
|
181
|
+
* const { client } = useSPFxMSGraphClient();
|
|
182
|
+
*
|
|
183
|
+
* if (!client) return <Spinner />;
|
|
184
|
+
*
|
|
185
|
+
* const batchRequest = async () => {
|
|
186
|
+
* const batch = {
|
|
187
|
+
* requests: [
|
|
188
|
+
* { id: '1', method: 'GET', url: '/me' },
|
|
189
|
+
* { id: '2', method: 'GET', url: '/me/messages?$top=5' }
|
|
190
|
+
* ]
|
|
191
|
+
* };
|
|
192
|
+
*
|
|
193
|
+
* const result = await client.api('/$batch').post(batch);
|
|
194
|
+
* console.log(result);
|
|
195
|
+
* };
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
export declare function useSPFxMSGraphClient(): SPFxMSGraphClientInfo;
|
|
200
|
+
//# sourceMappingURL=useSPFxMSGraphClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSPFxMSGraphClient.d.ts","sourceRoot":"","sources":["../../src/hooks/useSPFxMSGraphClient.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IAE7C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAEhF;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IAElC,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6JG;AACH,wBAAgB,oBAAoB,IAAI,qBAAqB,CAkE5D"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// useSPFxMSGraphClient.ts
|
|
2
|
+
// Hook to access Microsoft Graph client 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 Microsoft Graph client with built-in state management
|
|
43
|
+
*
|
|
44
|
+
* Provides native MSGraphClientV3 for authenticated Microsoft Graph 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, install @microsoft/microsoft-graph-types:
|
|
51
|
+
* ```bash
|
|
52
|
+
* npm install @microsoft/microsoft-graph-types --save-dev
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* And import SPFx types:
|
|
56
|
+
* ```typescript
|
|
57
|
+
* import type { MSGraphClientV3 } from '@microsoft/sp-http';
|
|
58
|
+
* import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Requirements:
|
|
62
|
+
* - MSGraphClientFactory available in SPFx context (v1.15.0+)
|
|
63
|
+
* - Appropriate Microsoft Graph permissions granted by admin
|
|
64
|
+
*
|
|
65
|
+
* @example Using invoke with state management
|
|
66
|
+
* ```tsx
|
|
67
|
+
* import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
|
|
68
|
+
*
|
|
69
|
+
* function UserProfile() {
|
|
70
|
+
* const { invoke, isLoading, error, clearError } = useSPFxMSGraphClient();
|
|
71
|
+
* const [user, setUser] = useState<MicrosoftGraph.User>();
|
|
72
|
+
*
|
|
73
|
+
* const loadUser = () => {
|
|
74
|
+
* invoke(client =>
|
|
75
|
+
* client.api('/me')
|
|
76
|
+
* .select('displayName,mail,jobTitle')
|
|
77
|
+
* .get()
|
|
78
|
+
* ).then(setUser);
|
|
79
|
+
* };
|
|
80
|
+
*
|
|
81
|
+
* useEffect(() => { loadUser(); }, []);
|
|
82
|
+
*
|
|
83
|
+
* if (isLoading) return <Spinner />;
|
|
84
|
+
* if (error) return (
|
|
85
|
+
* <MessageBar messageBarType={MessageBarType.error}>
|
|
86
|
+
* {error.message}
|
|
87
|
+
* <Link onClick={() => { clearError(); loadUser(); }}>Retry</Link>
|
|
88
|
+
* </MessageBar>
|
|
89
|
+
* );
|
|
90
|
+
*
|
|
91
|
+
* return <div>{user?.displayName}</div>;
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @example Using client directly for advanced control
|
|
96
|
+
* ```tsx
|
|
97
|
+
* import type { MSGraphClientV3 } from '@microsoft/sp-http';
|
|
98
|
+
* import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
|
|
99
|
+
*
|
|
100
|
+
* function MessagesList() {
|
|
101
|
+
* const { client } = useSPFxMSGraphClient();
|
|
102
|
+
* const [messages, setMessages] = useState<MicrosoftGraph.Message[]>([]);
|
|
103
|
+
* const [loading, setLoading] = useState(false);
|
|
104
|
+
*
|
|
105
|
+
* if (!client) return <Spinner label="Initializing Graph client..." />;
|
|
106
|
+
*
|
|
107
|
+
* const loadMessages = async () => {
|
|
108
|
+
* setLoading(true);
|
|
109
|
+
* try {
|
|
110
|
+
* const result = await client.api('/me/messages')
|
|
111
|
+
* .version('v1.0')
|
|
112
|
+
* .select('subject,from,receivedDateTime')
|
|
113
|
+
* .filter("importance eq 'high'")
|
|
114
|
+
* .orderBy('receivedDateTime DESC')
|
|
115
|
+
* .top(20)
|
|
116
|
+
* .get();
|
|
117
|
+
* setMessages(result.value);
|
|
118
|
+
* } catch (err) {
|
|
119
|
+
* console.error(err);
|
|
120
|
+
* } finally {
|
|
121
|
+
* setLoading(false);
|
|
122
|
+
* }
|
|
123
|
+
* };
|
|
124
|
+
*
|
|
125
|
+
* return (
|
|
126
|
+
* <>
|
|
127
|
+
* <button onClick={loadMessages} disabled={loading}>Load</button>
|
|
128
|
+
* {loading && <Spinner />}
|
|
129
|
+
* <MessageList items={messages} />
|
|
130
|
+
* </>
|
|
131
|
+
* );
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @example CRUD operations with invoke
|
|
136
|
+
* ```tsx
|
|
137
|
+
* function ContactsManager() {
|
|
138
|
+
* const { invoke, isLoading, error } = useSPFxMSGraphClient();
|
|
139
|
+
* const [contacts, setContacts] = useState([]);
|
|
140
|
+
*
|
|
141
|
+
* const loadContacts = () => {
|
|
142
|
+
* invoke(client =>
|
|
143
|
+
* client.api('/me/contacts').get()
|
|
144
|
+
* ).then(result => setContacts(result.value));
|
|
145
|
+
* };
|
|
146
|
+
*
|
|
147
|
+
* const createContact = (contact: any) => {
|
|
148
|
+
* invoke(client =>
|
|
149
|
+
* client.api('/me/contacts').post(contact)
|
|
150
|
+
* ).then(newContact => setContacts([...contacts, newContact]));
|
|
151
|
+
* };
|
|
152
|
+
*
|
|
153
|
+
* const updateContact = (id: string, changes: any) => {
|
|
154
|
+
* invoke(client =>
|
|
155
|
+
* client.api(`/me/contacts/${id}`).patch(changes)
|
|
156
|
+
* ).then(loadContacts);
|
|
157
|
+
* };
|
|
158
|
+
*
|
|
159
|
+
* const deleteContact = (id: string) => {
|
|
160
|
+
* invoke(client =>
|
|
161
|
+
* client.api(`/me/contacts/${id}`).delete()
|
|
162
|
+
* ).then(() => setContacts(contacts.filter(c => c.id !== id)));
|
|
163
|
+
* };
|
|
164
|
+
*
|
|
165
|
+
* return (
|
|
166
|
+
* <ContactsUI
|
|
167
|
+
* contacts={contacts}
|
|
168
|
+
* loading={isLoading}
|
|
169
|
+
* error={error}
|
|
170
|
+
* onCreate={createContact}
|
|
171
|
+
* onUpdate={updateContact}
|
|
172
|
+
* onDelete={deleteContact}
|
|
173
|
+
* />
|
|
174
|
+
* );
|
|
175
|
+
* }
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @example Batch operations with client
|
|
179
|
+
* ```tsx
|
|
180
|
+
* function BatchOperations() {
|
|
181
|
+
* const { client } = useSPFxMSGraphClient();
|
|
182
|
+
*
|
|
183
|
+
* if (!client) return <Spinner />;
|
|
184
|
+
*
|
|
185
|
+
* const batchRequest = async () => {
|
|
186
|
+
* const batch = {
|
|
187
|
+
* requests: [
|
|
188
|
+
* { id: '1', method: 'GET', url: '/me' },
|
|
189
|
+
* { id: '2', method: 'GET', url: '/me/messages?$top=5' }
|
|
190
|
+
* ]
|
|
191
|
+
* };
|
|
192
|
+
*
|
|
193
|
+
* const result = await client.api('/$batch').post(batch);
|
|
194
|
+
* console.log(result);
|
|
195
|
+
* };
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
export function useSPFxMSGraphClient() {
|
|
200
|
+
var _this = this;
|
|
201
|
+
var spfxContext = useSPFxContext().spfxContext;
|
|
202
|
+
var _a = useState(undefined), client = _a[0], setClient = _a[1];
|
|
203
|
+
var _b = useState(false), isLoading = _b[0], setIsLoading = _b[1];
|
|
204
|
+
var _c = useState(undefined), error = _c[0], setError = _c[1];
|
|
205
|
+
// Initialize Graph client
|
|
206
|
+
useEffect(function () {
|
|
207
|
+
var ctx = spfxContext;
|
|
208
|
+
if (!ctx.msGraphClientFactory) {
|
|
209
|
+
console.warn('MSGraphClientFactory not available in SPFx context');
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// Get MSGraphClientV3 (version 3 of Microsoft Graph JavaScript Client Library)
|
|
213
|
+
ctx.msGraphClientFactory
|
|
214
|
+
.getClient('3')
|
|
215
|
+
.then(function (graphClient) {
|
|
216
|
+
setClient(graphClient);
|
|
217
|
+
})
|
|
218
|
+
.catch(function (err) {
|
|
219
|
+
console.error('Failed to initialize MSGraphClient:', err);
|
|
220
|
+
});
|
|
221
|
+
}, [spfxContext]);
|
|
222
|
+
// Invoke with automatic state management
|
|
223
|
+
var invoke = useCallback(function (fn) { return __awaiter(_this, void 0, void 0, function () {
|
|
224
|
+
var result, err_1, error_1;
|
|
225
|
+
return __generator(this, function (_a) {
|
|
226
|
+
switch (_a.label) {
|
|
227
|
+
case 0:
|
|
228
|
+
if (!client) {
|
|
229
|
+
throw new Error('Graph client not initialized. Wait for client to be available.');
|
|
230
|
+
}
|
|
231
|
+
setIsLoading(true);
|
|
232
|
+
setError(undefined);
|
|
233
|
+
_a.label = 1;
|
|
234
|
+
case 1:
|
|
235
|
+
_a.trys.push([1, 3, 4, 5]);
|
|
236
|
+
return [4 /*yield*/, fn(client)];
|
|
237
|
+
case 2:
|
|
238
|
+
result = _a.sent();
|
|
239
|
+
return [2 /*return*/, result];
|
|
240
|
+
case 3:
|
|
241
|
+
err_1 = _a.sent();
|
|
242
|
+
error_1 = err_1 instanceof Error ? err_1 : new Error(String(err_1));
|
|
243
|
+
setError(error_1);
|
|
244
|
+
throw error_1;
|
|
245
|
+
case 4:
|
|
246
|
+
setIsLoading(false);
|
|
247
|
+
return [7 /*endfinally*/];
|
|
248
|
+
case 5: return [2 /*return*/];
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}); }, [client]);
|
|
252
|
+
// Clear error helper
|
|
253
|
+
var clearError = useCallback(function () {
|
|
254
|
+
setError(undefined);
|
|
255
|
+
}, []);
|
|
256
|
+
return {
|
|
257
|
+
client: client,
|
|
258
|
+
invoke: invoke,
|
|
259
|
+
isLoading: isLoading,
|
|
260
|
+
error: error,
|
|
261
|
+
clearError: clearError,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=useSPFxMSGraphClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSPFxMSGraphClient.js","sourceRoot":"","sources":["../../src/hooks/useSPFxMSGraphClient.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,8DAA8D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE9D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AA+ClD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6JG;AACH,MAAM,UAAU,oBAAoB;IAApC,iBAkEC;IAjES,IAAA,WAAW,GAAK,cAAc,EAAE,YAArB,CAAsB;IACnC,IAAA,KAAsB,QAAQ,CAA8B,SAAS,CAAC,EAArE,MAAM,QAAA,EAAE,SAAS,QAAoD,CAAC;IACvE,IAAA,KAA4B,QAAQ,CAAC,KAAK,CAAC,EAA1C,SAAS,QAAA,EAAE,YAAY,QAAmB,CAAC;IAC5C,IAAA,KAAoB,QAAQ,CAAoB,SAAS,CAAC,EAAzD,KAAK,QAAA,EAAE,QAAQ,QAA0C,CAAC;IAEjE,0BAA0B;IAC1B,SAAS,CAAC;QACR,IAAM,GAAG,GAAG,WAIX,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,+EAA+E;QAC/E,GAAG,CAAC,oBAAoB;aACrB,SAAS,CAAC,GAAG,CAAC;aACd,IAAI,CAAC,UAAC,WAA4B;YACjC,SAAS,CAAC,WAAW,CAAC,CAAC;QACzB,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,GAAU;YAChB,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,yCAAyC;IACzC,IAAM,MAAM,GAAG,WAAW,CACxB,UAAU,EAA2C;;;;;oBACnD,IAAI,CAAC,MAAM,EAAE,CAAC;wBACZ,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;oBACpF,CAAC;oBAED,YAAY,CAAC,IAAI,CAAC,CAAC;oBACnB,QAAQ,CAAC,SAAS,CAAC,CAAC;;;;oBAGH,qBAAM,EAAE,CAAC,MAAM,CAAC,EAAA;;oBAAzB,MAAM,GAAG,SAAgB;oBAC/B,sBAAO,MAAM,EAAC;;;oBAER,UAAQ,KAAG,YAAY,KAAK,CAAC,CAAC,CAAC,KAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAG,CAAC,CAAC,CAAC;oBAClE,QAAQ,CAAC,OAAK,CAAC,CAAC;oBAChB,MAAM,OAAK,CAAC;;oBAEZ,YAAY,CAAC,KAAK,CAAC,CAAC;;;;;SAEvB,EACD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,qBAAqB;IACrB,IAAM,UAAU,GAAG,WAAW,CAAC;QAC7B,QAAQ,CAAC,SAAS,CAAC,CAAC;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO;QACL,MAAM,QAAA;QACN,MAAM,QAAA;QACN,SAAS,WAAA;QACT,KAAK,OAAA;QACL,UAAU,YAAA;KACX,CAAC;AACJ,CAAC"}
|