@apvee/spfx-react-toolkit 1.2.0 → 1.3.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.
Files changed (144) hide show
  1. package/README.md +52 -7217
  2. package/lib/core/context.internal.d.ts +6 -1
  3. package/lib/core/context.internal.d.ts.map +1 -1
  4. package/lib/core/context.internal.js +6 -1
  5. package/lib/core/context.internal.js.map +1 -1
  6. package/lib/core/index.d.ts +21 -0
  7. package/lib/core/index.d.ts.map +1 -1
  8. package/lib/core/index.js +21 -0
  9. package/lib/core/index.js.map +1 -1
  10. package/lib/core/provider-application-customizer.d.ts.map +1 -1
  11. package/lib/core/provider-application-customizer.js.map +1 -1
  12. package/lib/core/provider-field-customizer.d.ts.map +1 -1
  13. package/lib/core/provider-field-customizer.js.map +1 -1
  14. package/lib/core/provider-listview-commandset.d.ts.map +1 -1
  15. package/lib/core/provider-listview-commandset.js.map +1 -1
  16. package/lib/core/provider-webpart.d.ts.map +1 -1
  17. package/lib/core/provider-webpart.js.map +1 -1
  18. package/lib/core/types.d.ts +2 -0
  19. package/lib/core/types.d.ts.map +1 -1
  20. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.d.ts +14 -0
  21. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.d.ts.map +1 -0
  22. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js +41 -0
  23. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js.map +1 -0
  24. package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.manifest.json +17 -0
  25. package/lib/extensions/spFxReactToolkitTest/loc/en-us.js +5 -0
  26. package/lib/hooks/index.d.ts +31 -0
  27. package/lib/hooks/index.d.ts.map +1 -1
  28. package/lib/hooks/index.js +31 -0
  29. package/lib/hooks/index.js.map +1 -1
  30. package/lib/hooks/useAsyncInvoke.internal.d.ts +58 -0
  31. package/lib/hooks/useAsyncInvoke.internal.d.ts.map +1 -0
  32. package/lib/hooks/useAsyncInvoke.internal.js +118 -0
  33. package/lib/hooks/useAsyncInvoke.internal.js.map +1 -0
  34. package/lib/hooks/useSPFxAadHttpClient.d.ts +46 -0
  35. package/lib/hooks/useSPFxAadHttpClient.d.ts.map +1 -1
  36. package/lib/hooks/useSPFxAadHttpClient.js +55 -80
  37. package/lib/hooks/useSPFxAadHttpClient.js.map +1 -1
  38. package/lib/hooks/useSPFxContainerInfo.d.ts +2 -0
  39. package/lib/hooks/useSPFxContainerInfo.d.ts.map +1 -1
  40. package/lib/hooks/useSPFxContainerInfo.js +2 -0
  41. package/lib/hooks/useSPFxContainerInfo.js.map +1 -1
  42. package/lib/hooks/useSPFxDisplayMode.d.ts +4 -0
  43. package/lib/hooks/useSPFxDisplayMode.d.ts.map +1 -1
  44. package/lib/hooks/useSPFxDisplayMode.js +4 -0
  45. package/lib/hooks/useSPFxDisplayMode.js.map +1 -1
  46. package/lib/hooks/useSPFxHttpClient.d.ts +22 -2
  47. package/lib/hooks/useSPFxHttpClient.d.ts.map +1 -1
  48. package/lib/hooks/useSPFxHttpClient.js +19 -76
  49. package/lib/hooks/useSPFxHttpClient.js.map +1 -1
  50. package/lib/hooks/useSPFxMSGraphClient.d.ts +50 -3
  51. package/lib/hooks/useSPFxMSGraphClient.d.ts.map +1 -1
  52. package/lib/hooks/useSPFxMSGraphClient.js +60 -77
  53. package/lib/hooks/useSPFxMSGraphClient.js.map +1 -1
  54. package/lib/hooks/useSPFxOneDriveAppData.d.ts +0 -1
  55. package/lib/hooks/useSPFxOneDriveAppData.d.ts.map +1 -1
  56. package/lib/hooks/useSPFxOneDriveAppData.js +352 -101
  57. package/lib/hooks/useSPFxOneDriveAppData.js.map +1 -1
  58. package/lib/hooks/useSPFxPermissions.d.ts +15 -3
  59. package/lib/hooks/useSPFxPermissions.d.ts.map +1 -1
  60. package/lib/hooks/useSPFxPermissions.js.map +1 -1
  61. package/lib/hooks/useSPFxPnPContext.d.ts +4 -0
  62. package/lib/hooks/useSPFxPnPContext.d.ts.map +1 -1
  63. package/lib/hooks/useSPFxPnPContext.js +4 -0
  64. package/lib/hooks/useSPFxPnPContext.js.map +1 -1
  65. package/lib/hooks/useSPFxPnPSearch.d.ts.map +1 -1
  66. package/lib/hooks/useSPFxPnPSearch.js +61 -48
  67. package/lib/hooks/useSPFxPnPSearch.js.map +1 -1
  68. package/lib/hooks/useSPFxSPHttpClient.d.ts +18 -2
  69. package/lib/hooks/useSPFxSPHttpClient.d.ts.map +1 -1
  70. package/lib/hooks/useSPFxSPHttpClient.js +15 -75
  71. package/lib/hooks/useSPFxSPHttpClient.js.map +1 -1
  72. package/lib/hooks/useSPFxThemeInfo.d.ts +2 -0
  73. package/lib/hooks/useSPFxThemeInfo.d.ts.map +1 -1
  74. package/lib/hooks/useSPFxThemeInfo.js +2 -0
  75. package/lib/hooks/useSPFxThemeInfo.js.map +1 -1
  76. package/lib/index.d.ts +27 -0
  77. package/lib/index.d.ts.map +1 -1
  78. package/lib/index.js +27 -0
  79. package/lib/index.js.map +1 -1
  80. package/lib/utils/resize-observer.internal.d.ts +12 -2
  81. package/lib/utils/resize-observer.internal.d.ts.map +1 -1
  82. package/lib/utils/resize-observer.internal.js +12 -2
  83. package/lib/utils/resize-observer.internal.js.map +1 -1
  84. package/lib/utils/theme-subscription.internal.d.ts +12 -3
  85. package/lib/utils/theme-subscription.internal.d.ts.map +1 -1
  86. package/lib/utils/theme-subscription.internal.js +19 -3
  87. package/lib/utils/theme-subscription.internal.js.map +1 -1
  88. package/lib/utils/type-guards.internal.d.ts +78 -5
  89. package/lib/utils/type-guards.internal.d.ts.map +1 -1
  90. package/lib/utils/type-guards.internal.js +78 -5
  91. package/lib/utils/type-guards.internal.js.map +1 -1
  92. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts +0 -4
  93. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts.map +1 -1
  94. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js +30 -746
  95. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js.map +1 -1
  96. package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.d.ts +7 -0
  97. package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.d.ts.map +1 -0
  98. package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js +131 -0
  99. package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js.map +1 -0
  100. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.d.ts +8 -0
  101. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.d.ts.map +1 -0
  102. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js +158 -0
  103. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js.map +1 -0
  104. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.d.ts +9 -0
  105. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.d.ts.map +1 -0
  106. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js +159 -0
  107. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js.map +1 -0
  108. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.d.ts +10 -0
  109. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.d.ts.map +1 -0
  110. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js +141 -0
  111. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js.map +1 -0
  112. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.d.ts +6 -0
  113. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.d.ts.map +1 -0
  114. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js +62 -0
  115. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js.map +1 -0
  116. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.d.ts +6 -0
  117. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.d.ts.map +1 -0
  118. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js +98 -0
  119. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js.map +1 -0
  120. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.d.ts +6 -0
  121. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.d.ts.map +1 -0
  122. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js +45 -0
  123. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js.map +1 -0
  124. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.d.ts +6 -0
  125. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.d.ts.map +1 -0
  126. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js +134 -0
  127. package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js.map +1 -0
  128. package/lib/webparts/spFxReactToolkitTest/components/demos/index.d.ts +13 -0
  129. package/lib/webparts/spFxReactToolkitTest/components/demos/index.d.ts.map +1 -0
  130. package/lib/webparts/spFxReactToolkitTest/components/demos/index.js +18 -0
  131. package/lib/webparts/spFxReactToolkitTest/components/demos/index.js.map +1 -0
  132. package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.d.ts +18 -0
  133. package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.d.ts.map +1 -0
  134. package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js +17 -0
  135. package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js.map +1 -0
  136. package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.d.ts +16 -0
  137. package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.d.ts.map +1 -0
  138. package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js +14 -0
  139. package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js.map +1 -0
  140. package/lib/webparts/spFxReactToolkitTest/components/shared/index.d.ts +6 -0
  141. package/lib/webparts/spFxReactToolkitTest/components/shared/index.d.ts.map +1 -0
  142. package/lib/webparts/spFxReactToolkitTest/components/shared/index.js +6 -0
  143. package/lib/webparts/spFxReactToolkitTest/components/shared/index.js.map +1 -0
  144. package/package.json +14 -12
@@ -46,723 +46,11 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
46
46
  import * as React from 'react';
47
47
  import styles from './SpFxReactToolkitTest.module.scss';
48
48
  import { Stack, Pivot, PivotItem, TextField, PrimaryButton, DefaultButton, MessageBar, MessageBarType, Separator, Label, Icon, } from '@fluentui/react';
49
- /* eslint-disable max-lines */
50
- // Import all hooks from SPFx React Toolkit
51
- import { useSPFxProperties, useSPFxThemeInfo, useSPFxUserInfo, useSPFxEnvironmentInfo, useSPFxSiteInfo, useSPFxDisplayMode, useSPFxInstanceInfo, useSPFxPageContext, useSPFxTeams, useSPFxListInfo, useSPFxLocaleInfo, useSPFxHubSiteInfo, useSPFxCorrelationInfo, useSPFxPermissions, useSPFxCrossSitePermissions, useSPFxContainerSize, useSPFxContainerInfo, useSPFxSessionStorage, useSPFxLocalStorage, useSPFxLogger, useSPFxPageType, useSPFxServiceScope, useSPFxSPHttpClient, useSPFxMSGraphClient, useSPFxAadHttpClient, useSPFxHttpClient, useSPFxPerformance, useSPFxFluent9ThemeInfo, useSPFxOneDriveAppData, useSPFxTenantProperty, useSPFxUserPhoto, useSPFxPnPContext, useSPFxPnP, useSPFxPnPList, useSPFxPnPSearch, SearchVerticals, } from '../../../hooks';
52
- import '@pnp/sp/webs';
53
- import '@pnp/sp/lists';
54
- import '@pnp/sp/items';
55
- import '@pnp/sp/site-users';
49
+ import { InfoRow, StatusBadge } from './shared';
50
+ import { HttpClientDemo, PnPContextDemo, PnPOperationsDemo, PnPListDemo, PnPSearchBasicDemo, PnPSearchAdvancedDemo, PnPSearchRefinersDemo, PnPSearchSuggestionsDemo, } from './demos';
51
+ // Import hooks from SPFx React Toolkit (used in main component)
52
+ import { useSPFxProperties, useSPFxThemeInfo, useSPFxUserInfo, useSPFxEnvironmentInfo, useSPFxSiteInfo, useSPFxDisplayMode, useSPFxInstanceInfo, useSPFxPageContext, useSPFxTeams, useSPFxListInfo, useSPFxLocaleInfo, useSPFxHubSiteInfo, useSPFxCorrelationInfo, useSPFxPermissions, useSPFxCrossSitePermissions, useSPFxContainerSize, useSPFxContainerInfo, useSPFxSessionStorage, useSPFxLocalStorage, useSPFxLogger, useSPFxPageType, useSPFxServiceScope, useSPFxSPHttpClient, useSPFxMSGraphClient, useSPFxAadHttpClient, useSPFxPerformance, useSPFxFluent9ThemeInfo, useSPFxOneDriveAppData, useSPFxTenantProperty, useSPFxUserPhoto, } from '../../../hooks';
56
53
  import { SPPermission } from '@microsoft/sp-page-context';
57
- import { HttpClient } from '@microsoft/sp-http';
58
- // =============================================
59
- // Helper Components (Must be defined first)
60
- // =============================================
61
- // Helper component for displaying info rows
62
- var InfoRow = function (_a) {
63
- var label = _a.label, value = _a.value, icon = _a.icon;
64
- return (React.createElement("div", { className: styles.infoRow },
65
- icon && React.createElement(Icon, { iconName: icon }),
66
- React.createElement(Label, null,
67
- label,
68
- ":"),
69
- React.createElement("span", null, value || 'N/A')));
70
- };
71
- // Helper component for status badges
72
- var StatusBadge = function (_a) {
73
- var available = _a.available, label = _a.label;
74
- return (React.createElement("div", { className: "".concat(styles.statusBadge, " ").concat(available ? styles.success : styles.error) },
75
- React.createElement(Icon, { iconName: available ? 'Completed' : 'ErrorBadge' }),
76
- label));
77
- };
78
- // =============================================
79
- // HttpClient Example Component
80
- // =============================================
81
- /**
82
- * Example: useSPFxHttpClient
83
- * Demonstrates calling external public APIs using HttpClient
84
- */
85
- var HttpClientExample = function () {
86
- var _a = useSPFxHttpClient(), invoke = _a.invoke, isLoading = _a.isLoading, error = _a.error, clearError = _a.clearError;
87
- var _b = React.useState([]), todos = _b[0], setTodos = _b[1];
88
- var _c = React.useState(null), selectedTodo = _c[0], setSelectedTodo = _c[1];
89
- var loadTodos = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
90
- var data, err_1;
91
- return __generator(this, function (_a) {
92
- switch (_a.label) {
93
- case 0:
94
- _a.trys.push([0, 2, , 3]);
95
- return [4 /*yield*/, invoke(function (client) {
96
- return client.get('https://jsonplaceholder.typicode.com/todos?_limit=5', HttpClient.configurations.v1).then(function (res) { return res.json(); });
97
- })];
98
- case 1:
99
- data = _a.sent();
100
- setTodos(data);
101
- setSelectedTodo(null);
102
- return [3 /*break*/, 3];
103
- case 2:
104
- err_1 = _a.sent();
105
- console.error('Failed to load todos:', err_1);
106
- return [3 /*break*/, 3];
107
- case 3: return [2 /*return*/];
108
- }
109
- });
110
- }); }, [invoke]);
111
- var loadTodoDetails = React.useCallback(function (id) { return __awaiter(void 0, void 0, void 0, function () {
112
- var data, err_2;
113
- return __generator(this, function (_a) {
114
- switch (_a.label) {
115
- case 0:
116
- _a.trys.push([0, 2, , 3]);
117
- return [4 /*yield*/, invoke(function (client) {
118
- return client.get("https://jsonplaceholder.typicode.com/todos/".concat(id), HttpClient.configurations.v1).then(function (res) { return res.json(); });
119
- })];
120
- case 1:
121
- data = _a.sent();
122
- setSelectedTodo(data);
123
- return [3 /*break*/, 3];
124
- case 2:
125
- err_2 = _a.sent();
126
- console.error('Failed to load todo details:', err_2);
127
- return [3 /*break*/, 3];
128
- case 3: return [2 /*return*/];
129
- }
130
- });
131
- }); }, [invoke]);
132
- return (React.createElement(Stack, { tokens: { childrenGap: 15 }, styles: { root: { padding: '16px', border: '1px solid #ddd', borderRadius: '4px' } } },
133
- React.createElement("h3", null,
134
- React.createElement(Icon, { iconName: "CloudDownload", style: { marginRight: '8px' } }),
135
- "HttpClient Example - Public API Call"),
136
- React.createElement(MessageBar, { messageBarType: MessageBarType.info },
137
- "This example demonstrates calling a public REST API (JSONPlaceholder) using ",
138
- React.createElement("strong", null, "useSPFxHttpClient"),
139
- ". The hook provides automatic state management (loading/error) for external HTTP calls."),
140
- React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 10 } },
141
- React.createElement(PrimaryButton, { text: "Load Todos", onClick: loadTodos, disabled: isLoading, iconProps: { iconName: 'Download' } }),
142
- error && (React.createElement(DefaultButton, { text: "Clear Error", onClick: clearError, iconProps: { iconName: 'Clear' } }))),
143
- isLoading && (React.createElement(MessageBar, { messageBarType: MessageBarType.info },
144
- React.createElement(Icon, { iconName: "Sync", style: { marginRight: '8px' } }),
145
- "Loading data from external API...")),
146
- error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error },
147
- React.createElement("strong", null, "Error:"),
148
- " ",
149
- error.message)),
150
- todos.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 10 } },
151
- React.createElement(Label, null, "Todos from JSONPlaceholder API:"),
152
- todos.map(function (todo) { return (React.createElement(Stack, { key: todo.id, horizontal: true, tokens: { childrenGap: 10 }, styles: {
153
- root: {
154
- padding: '8px',
155
- border: '1px solid #eee',
156
- borderRadius: '4px',
157
- cursor: 'pointer',
158
- ':hover': { backgroundColor: '#f5f5f5' }
159
- }
160
- }, onClick: function () { return loadTodoDetails(todo.id); } },
161
- React.createElement(Icon, { iconName: todo.completed ? 'CompletedSolid' : 'CircleRing' }),
162
- React.createElement("span", null, todo.title))); }))),
163
- selectedTodo && (React.createElement(Stack, { tokens: { childrenGap: 8 }, styles: { root: { padding: '12px', backgroundColor: '#f0f0f0', borderRadius: '4px' } } },
164
- React.createElement(Label, null, "Selected Todo Details:"),
165
- React.createElement(InfoRow, { label: "ID", value: String(selectedTodo.id), icon: "NumberField" }),
166
- React.createElement(InfoRow, { label: "User ID", value: String(selectedTodo.userId), icon: "Contact" }),
167
- React.createElement(InfoRow, { label: "Title", value: selectedTodo.title, icon: "TextDocument" }),
168
- React.createElement(InfoRow, { label: "Completed", value: selectedTodo.completed ? 'Yes' : 'No', icon: selectedTodo.completed ? 'CompletedSolid' : 'CircleRing' })))));
169
- };
170
- // =============================================
171
- // PnPjs Example Components
172
- // =============================================
173
- /**
174
- * Example 1: useSPFxPnPContext
175
- * Shows how to create PnP contexts for current and cross-site scenarios
176
- */
177
- var PnPContextExample = function () {
178
- var _a = React.useState(''), crossSiteUrl = _a[0], setCrossSiteUrl = _a[1];
179
- var _b = React.useState(null), siteInfo = _b[0], setSiteInfo = _b[1];
180
- var _c = React.useState(false), loading = _c[0], setLoading = _c[1];
181
- var _d = React.useState(null), errorMsg = _d[0], setErrorMsg = _d[1];
182
- // Current site context (default)
183
- var currentContext = useSPFxPnPContext();
184
- // Cross-site context (only when URL is provided)
185
- var crossSiteContext = useSPFxPnPContext(crossSiteUrl || undefined);
186
- var handleLoadCurrentSite = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
187
- var web, error_1;
188
- return __generator(this, function (_a) {
189
- switch (_a.label) {
190
- case 0:
191
- if (!currentContext.sp)
192
- return [2 /*return*/];
193
- setLoading(true);
194
- setErrorMsg(null);
195
- _a.label = 1;
196
- case 1:
197
- _a.trys.push([1, 3, 4, 5]);
198
- return [4 /*yield*/, currentContext.sp.web.select('Title', 'Url', 'Description')()];
199
- case 2:
200
- web = _a.sent();
201
- setSiteInfo({
202
- title: web.Title,
203
- url: web.Url,
204
- description: web.Description || '(no description)'
205
- });
206
- return [3 /*break*/, 5];
207
- case 3:
208
- error_1 = _a.sent();
209
- console.error('Error loading site:', error_1);
210
- setErrorMsg(error_1 instanceof Error ? error_1.message : 'Unknown error');
211
- setSiteInfo(null);
212
- return [3 /*break*/, 5];
213
- case 4:
214
- setLoading(false);
215
- return [7 /*endfinally*/];
216
- case 5: return [2 /*return*/];
217
- }
218
- });
219
- }); }, [currentContext.sp]);
220
- var handleLoadCrossSite = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
221
- var web, error_2;
222
- return __generator(this, function (_a) {
223
- switch (_a.label) {
224
- case 0:
225
- if (!crossSiteContext.sp || !crossSiteUrl)
226
- return [2 /*return*/];
227
- setLoading(true);
228
- setErrorMsg(null);
229
- _a.label = 1;
230
- case 1:
231
- _a.trys.push([1, 3, 4, 5]);
232
- return [4 /*yield*/, crossSiteContext.sp.web.select('Title', 'Url', 'Description')()];
233
- case 2:
234
- web = _a.sent();
235
- setSiteInfo({
236
- title: web.Title,
237
- url: web.Url,
238
- description: web.Description || '(no description)'
239
- });
240
- return [3 /*break*/, 5];
241
- case 3:
242
- error_2 = _a.sent();
243
- console.error('Error loading cross-site:', error_2);
244
- setErrorMsg(error_2 instanceof Error ? error_2.message : 'Unknown error');
245
- setSiteInfo(null);
246
- return [3 /*break*/, 5];
247
- case 4:
248
- setLoading(false);
249
- return [7 /*endfinally*/];
250
- case 5: return [2 /*return*/];
251
- }
252
- });
253
- }); }, [crossSiteContext.sp, crossSiteUrl]);
254
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
255
- React.createElement("h3", null,
256
- React.createElement(Icon, { iconName: "Globe", style: { marginRight: '8px' } }),
257
- "Example 1: useSPFxPnPContext - Site Information"),
258
- React.createElement(Separator, null),
259
- errorMsg && (React.createElement(MessageBar, { messageBarType: MessageBarType.error, onDismiss: function () { return setErrorMsg(null); } }, errorMsg)),
260
- React.createElement(Stack, { tokens: { childrenGap: 8 } },
261
- React.createElement(Label, null, "Current Site Context"),
262
- React.createElement(InfoRow, { label: "Effective URL", value: currentContext.siteUrl, icon: "Link" }),
263
- React.createElement(InfoRow, { label: "Is Initialized", value: currentContext.isInitialized ? 'Yes' : 'No', icon: "CheckMark" }),
264
- currentContext.error && (React.createElement(MessageBar, { messageBarType: MessageBarType.warning },
265
- "Init Error: ",
266
- currentContext.error.message)),
267
- React.createElement(PrimaryButton, { text: loading ? 'Loading...' : 'Load Current Site Info', onClick: handleLoadCurrentSite, disabled: !currentContext.isInitialized || loading, iconProps: { iconName: 'CloudDownload' } })),
268
- React.createElement(Stack, { tokens: { childrenGap: 8 } },
269
- React.createElement(Label, null, "Cross-Site Context (Optional)"),
270
- React.createElement(TextField, { label: "Site URL", value: crossSiteUrl, onChange: function (_, newValue) { return setCrossSiteUrl(newValue !== null && newValue !== void 0 ? newValue : ''); }, placeholder: "e.g., /sites/hr or https://contoso.sharepoint.com/sites/hr", description: "Leave empty to use current site" }),
271
- crossSiteUrl && (React.createElement(React.Fragment, null,
272
- React.createElement(InfoRow, { label: "Resolved URL", value: crossSiteContext.siteUrl, icon: "Link" }),
273
- React.createElement(InfoRow, { label: "Is Initialized", value: crossSiteContext.isInitialized ? 'Yes' : 'No', icon: "CheckMark" }),
274
- crossSiteContext.error && (React.createElement(MessageBar, { messageBarType: MessageBarType.warning },
275
- "Init Error: ",
276
- crossSiteContext.error.message)),
277
- React.createElement(PrimaryButton, { text: loading ? 'Loading...' : 'Load Cross-Site Info', onClick: handleLoadCrossSite, disabled: !crossSiteContext.isInitialized || loading, iconProps: { iconName: 'Globe' } })))),
278
- siteInfo && (React.createElement(Stack, { tokens: { childrenGap: 8 }, styles: { root: { padding: '12px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
279
- React.createElement(Label, { style: { fontWeight: 600 } },
280
- React.createElement(Icon, { iconName: "CheckMark", style: { marginRight: '4px', color: '#107c10' } }),
281
- "Site Information Loaded:"),
282
- React.createElement(InfoRow, { label: "Title", value: siteInfo.title, icon: "CityNext" }),
283
- React.createElement(InfoRow, { label: "URL", value: siteInfo.url, icon: "Link" }),
284
- React.createElement(InfoRow, { label: "Description", value: siteInfo.description, icon: "Info" }))),
285
- React.createElement(Label, null,
286
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
287
- "useSPFxPnPContext creates configured SPFI instances. Use for cross-site scenarios or when you need custom cache/batch config.")));
288
- };
289
- /**
290
- * Example 2: useSPFxPnP
291
- * Shows invoke() for single operations and batch() for multiple operations
292
- */
293
- var PnPOperationsExample = function () {
294
- var _a = useSPFxPnP(), invoke = _a.invoke, batch = _a.batch, isLoading = _a.isLoading, error = _a.error, clearError = _a.clearError;
295
- var _b = React.useState([]), lists = _b[0], setLists = _b[1];
296
- var _c = React.useState(null), batchData = _c[0], setBatchData = _c[1];
297
- var handleInvokeLists = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
298
- var result, err_3;
299
- return __generator(this, function (_a) {
300
- switch (_a.label) {
301
- case 0:
302
- _a.trys.push([0, 2, , 3]);
303
- clearError();
304
- return [4 /*yield*/, invoke(function (sp) {
305
- return sp.web.lists
306
- .select('Title', 'ItemCount')
307
- .filter('Hidden eq false')
308
- .top(10)();
309
- })];
310
- case 1:
311
- result = _a.sent();
312
- setLists(result);
313
- return [3 /*break*/, 3];
314
- case 2:
315
- err_3 = _a.sent();
316
- console.error('Invoke error:', err_3);
317
- return [3 /*break*/, 3];
318
- case 3: return [2 /*return*/];
319
- }
320
- });
321
- }); }, [invoke, clearError]);
322
- var handleBatchOperations = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
323
- var results, listsResult, userResult, webResult, err_4;
324
- return __generator(this, function (_a) {
325
- switch (_a.label) {
326
- case 0:
327
- _a.trys.push([0, 2, , 3]);
328
- clearError();
329
- return [4 /*yield*/, batch(function (batchedSP) { return __awaiter(void 0, void 0, void 0, function () {
330
- var listsPromise, userPromise, webPromise;
331
- return __generator(this, function (_a) {
332
- listsPromise = batchedSP.web.lists.select('Title').top(5)();
333
- userPromise = batchedSP.web.currentUser.select('Title')();
334
- webPromise = batchedSP.web.select('Title')();
335
- // Wait for all batched operations to complete
336
- return [2 /*return*/, Promise.all([listsPromise, userPromise, webPromise])];
337
- });
338
- }); })];
339
- case 1:
340
- results = _a.sent();
341
- listsResult = results[0], userResult = results[1], webResult = results[2];
342
- setBatchData({
343
- lists: listsResult,
344
- user: userResult,
345
- webTitle: webResult.Title
346
- });
347
- return [3 /*break*/, 3];
348
- case 2:
349
- err_4 = _a.sent();
350
- console.error('Batch error:', err_4);
351
- return [3 /*break*/, 3];
352
- case 3: return [2 /*return*/];
353
- }
354
- });
355
- }); }, [batch, clearError]);
356
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
357
- React.createElement("h3", null,
358
- React.createElement(Icon, { iconName: "CloudUpload", style: { marginRight: '8px' } }),
359
- "Example 2: useSPFxPnP - Operations & Batching"),
360
- React.createElement(Separator, null),
361
- error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error, onDismiss: clearError }, error.message)),
362
- React.createElement(Stack, { tokens: { childrenGap: 8 } },
363
- React.createElement(Label, null, "Single Operation with invoke()"),
364
- React.createElement(PrimaryButton, { text: isLoading ? 'Loading...' : 'Load Lists (invoke)', onClick: handleInvokeLists, disabled: isLoading, iconProps: { iconName: 'BulletedList' } }),
365
- lists.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 4 }, styles: { root: { padding: '12px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
366
- React.createElement(Label, null, "Lists (top 10, non-hidden):"),
367
- lists.map(function (list, idx) { return (React.createElement("div", { key: idx, style: { padding: '4px 0', borderBottom: idx < lists.length - 1 ? '1px solid #edebe9' : 'none' } },
368
- React.createElement("strong", null, list.Title),
369
- " - ",
370
- list.ItemCount,
371
- " items")); })))),
372
- React.createElement(Stack, { tokens: { childrenGap: 8 } },
373
- React.createElement(Label, null, "Batch Operations with batch()"),
374
- React.createElement(PrimaryButton, { text: isLoading ? 'Loading...' : 'Load Multiple (batch)', onClick: handleBatchOperations, disabled: isLoading, iconProps: { iconName: 'Streaming' } }),
375
- batchData && (React.createElement(Stack, { tokens: { childrenGap: 8 }, styles: { root: { padding: '12px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
376
- React.createElement(InfoRow, { label: "Web Title", value: batchData.webTitle, icon: "CityNext" }),
377
- React.createElement(InfoRow, { label: "Current User", value: batchData.user.Title, icon: "Contact" }),
378
- React.createElement(Label, null, "Lists (top 5):"),
379
- batchData.lists.map(function (list, idx) { return (React.createElement("div", { key: idx, style: { paddingLeft: '16px' } },
380
- "\u2022 ",
381
- list.Title)); })))),
382
- React.createElement(Label, null,
383
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
384
- "invoke() for single operations, batch() combines multiple requests into ONE HTTP call for better performance.")));
385
- };
386
- /**
387
- * Example 3: useSPFxPnPSearch - Basic Search
388
- */
389
- var PnPSearchBasicExample = function () {
390
- var _a = React.useState(''), searchText = _a[0], setSearchText = _a[1];
391
- var _b = useSPFxPnPSearch({
392
- pageSize: 10
393
- }), search = _b.search, results = _b.results, totalResults = _b.totalResults, loading = _b.loading, error = _b.error, clearError = _b.clearError;
394
- var handleSearch = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
395
- var searchResults, err_5;
396
- return __generator(this, function (_a) {
397
- switch (_a.label) {
398
- case 0:
399
- if (!searchText.trim())
400
- return [2 /*return*/];
401
- _a.label = 1;
402
- case 1:
403
- _a.trys.push([1, 3, , 4]);
404
- return [4 /*yield*/, search(searchText)];
405
- case 2:
406
- searchResults = _a.sent();
407
- console.log('[PnPSearchBasic] Search completed:', {
408
- returnedResults: searchResults.length,
409
- stateResults: results.length,
410
- totalResults: totalResults
411
- });
412
- return [3 /*break*/, 4];
413
- case 3:
414
- err_5 = _a.sent();
415
- console.error('Search error:', err_5);
416
- return [3 /*break*/, 4];
417
- case 4: return [2 /*return*/];
418
- }
419
- });
420
- }); }, [searchText, search, results.length, totalResults]);
421
- // Debug: log quando results cambia
422
- React.useEffect(function () {
423
- console.log('[PnPSearchBasic] Results state updated:', {
424
- resultsLength: results.length,
425
- totalResults: totalResults,
426
- loading: loading
427
- });
428
- }, [results, totalResults, loading]);
429
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
430
- React.createElement("h3", null,
431
- React.createElement(Icon, { iconName: "Search", style: { marginRight: '8px' } }),
432
- "Example 1: Basic Search"),
433
- React.createElement(Separator, null),
434
- error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error, onDismiss: clearError }, error.message)),
435
- React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 8 } },
436
- React.createElement(TextField, { value: searchText, onChange: function (_, newValue) { return setSearchText(newValue !== null && newValue !== void 0 ? newValue : ''); }, placeholder: "Search SharePoint...", styles: { root: { flexGrow: 1 } }, onKeyDown: function (e) {
437
- if (e.key === 'Enter') {
438
- handleSearch().catch(function (err) { return console.error('Search error:', err); });
439
- }
440
- } }),
441
- React.createElement(PrimaryButton, { text: loading ? 'Searching...' : 'Search', onClick: handleSearch, disabled: !searchText.trim() || loading, iconProps: { iconName: 'Search' } })),
442
- totalResults !== undefined && (React.createElement(MessageBar, { messageBarType: MessageBarType.info },
443
- "Found ",
444
- totalResults,
445
- " result",
446
- totalResults !== 1 ? 's' : '')),
447
- results.length > 0 ? (React.createElement(Stack, { tokens: { childrenGap: 6 } }, results.map(function (result) { return (React.createElement(Stack, { key: result.id, tokens: { childrenGap: 4 }, styles: { root: { padding: '10px', backgroundColor: '#faf9f8', borderRadius: '4px' } } },
448
- React.createElement("div", { style: { fontWeight: 600 } }, result.data.Title || '(No Title)'),
449
- React.createElement("a", { href: result.data.Path, target: "_blank", rel: "noopener noreferrer", style: { fontSize: '12px' } }, result.data.Path),
450
- result.data.FileType && React.createElement(Label, null,
451
- "Type: ",
452
- result.data.FileType))); }))) : totalResults === 0 ? (React.createElement(MessageBar, null, "No results found. Try a different query.")) : null,
453
- React.createElement(Label, null,
454
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
455
- "Simple text search. Try: \"document\", \"report\", \"ContentType:Document\"")));
456
- };
457
- /**
458
- * Example 4: Advanced Search with Builder and Verticals
459
- */
460
- var PnPSearchAdvancedExample = function () {
461
- var _a = React.useState('All'), selectedVertical = _a[0], setSelectedVertical = _a[1];
462
- var _b = useSPFxPnPSearch({
463
- pageSize: 5,
464
- selectProperties: ['Title', 'Path', 'Author', 'LastModifiedTime', 'FileType']
465
- }), search = _b.search, results = _b.results, totalResults = _b.totalResults, loading = _b.loading, loadMore = _b.loadMore, hasMore = _b.hasMore, error = _b.error, clearError = _b.clearError;
466
- var getVerticalSourceId = function (vertical) {
467
- switch (vertical) {
468
- case 'People': return SearchVerticals.People;
469
- case 'Documents': return SearchVerticals.Documents;
470
- case 'Pages': return SearchVerticals.Pages;
471
- case 'Videos': return SearchVerticals.Videos;
472
- default: return undefined;
473
- }
474
- };
475
- var handleSearch = React.useCallback(function (query) {
476
- search(function (builder) {
477
- var result = builder.text(query).sortList({ Property: 'LastModifiedTime', Direction: 1 });
478
- var sourceId = getVerticalSourceId(selectedVertical);
479
- if (sourceId)
480
- result = result.sourceId(sourceId);
481
- return result;
482
- }).catch(function (err) { return console.error('Search error:', err); });
483
- }, [search, selectedVertical]);
484
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
485
- React.createElement("h3", null,
486
- React.createElement(Icon, { iconName: "SearchAndApps", style: { marginRight: '8px' } }),
487
- "Example 2: Advanced Search with Builder"),
488
- React.createElement(Separator, null),
489
- error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error, onDismiss: clearError }, error.message)),
490
- React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 6 }, wrap: true }, ['All', 'Documents', 'Pages', 'People', 'Videos'].map(function (v) { return (React.createElement(DefaultButton, { key: v, text: v, onClick: function () { return setSelectedVertical(v); }, primary: selectedVertical === v })); })),
491
- React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 6 } },
492
- React.createElement(PrimaryButton, { text: "Search All", onClick: function () { return handleSearch('*'); }, disabled: loading }),
493
- React.createElement(DefaultButton, { text: "Search Documents", onClick: function () { return handleSearch('filetype:docx OR filetype:pdf'); }, disabled: loading })),
494
- totalResults !== undefined && (React.createElement(MessageBar, { messageBarType: MessageBarType.info },
495
- "Found ",
496
- totalResults,
497
- " result",
498
- totalResults !== 1 ? 's' : '',
499
- " in \"",
500
- selectedVertical,
501
- "\"")),
502
- results.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 6 } },
503
- results.map(function (result) { return (React.createElement(Stack, { key: result.id, tokens: { childrenGap: 2 }, styles: { root: { padding: '10px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
504
- React.createElement("div", { style: { fontWeight: 600 } }, result.data.Title || '(No Title)'),
505
- React.createElement(Label, null,
506
- result.data.Author,
507
- " - ",
508
- result.data.LastModifiedTime ? new Date(result.data.LastModifiedTime).toLocaleDateString() : 'N/A'),
509
- React.createElement("a", { href: result.data.Path, target: "_blank", rel: "noopener noreferrer", style: { fontSize: '11px' } }, result.data.Path))); }),
510
- hasMore && (React.createElement(PrimaryButton, { text: loading ? 'Loading...' : 'Load More', onClick: loadMore, disabled: loading })))),
511
- React.createElement(Label, null,
512
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
513
- "Builder API with verticals (People, Documents, Pages, Videos) and pagination.")));
514
- };
515
- /**
516
- * Example 5: Faceted Search with Refiners
517
- */
518
- var PnPSearchRefinersExample = function () {
519
- var _a = useSPFxPnPSearch({
520
- pageSize: 10,
521
- selectProperties: ['Title', 'Path', 'FileType', 'Author'],
522
- refiners: 'FileType,Author'
523
- }), search = _a.search, results = _a.results, refiners = _a.refiners, totalResults = _a.totalResults, loading = _a.loading, applyRefiner = _a.applyRefiner, error = _a.error, clearError = _a.clearError;
524
- var handleSearch = React.useCallback(function () {
525
- search('*').catch(function (err) { return console.error('Search error:', err); });
526
- }, [search]);
527
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
528
- React.createElement("h3", null,
529
- React.createElement(Icon, { iconName: "FilterSettings", style: { marginRight: '8px' } }),
530
- "Example 3: Faceted Search with Refiners"),
531
- React.createElement(Separator, null),
532
- error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error, onDismiss: clearError }, error.message)),
533
- React.createElement(PrimaryButton, { text: loading ? 'Loading...' : 'Search All Content', onClick: handleSearch, disabled: loading, iconProps: { iconName: 'Search' } }),
534
- totalResults !== undefined && (React.createElement(Label, null,
535
- React.createElement(Icon, { iconName: "SearchIssue", style: { marginRight: '4px', color: '#0078d4' } }),
536
- "Found ",
537
- totalResults,
538
- " results")),
539
- React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 12 }, styles: { root: { alignItems: 'flex-start' } } },
540
- refiners.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 8 }, styles: { root: { width: '200px', padding: '8px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
541
- React.createElement(Label, { style: { fontWeight: 600 } }, "Filters"),
542
- refiners.map(function (refiner) { return (React.createElement(Stack, { key: refiner.name, tokens: { childrenGap: 2 } },
543
- React.createElement(Label, null, refiner.name),
544
- refiner.entries.slice(0, 5).map(function (entry) { return (React.createElement(DefaultButton, { key: entry.value, text: "".concat(entry.value, " (").concat(entry.count, ")"), onClick: function () { return applyRefiner(refiner.name, entry.value); }, styles: { root: { height: '28px', fontSize: '12px' } } })); }))); }))),
545
- React.createElement(Stack, { tokens: { childrenGap: 6 }, styles: { root: { flexGrow: 1 } } }, results.length > 0 ? (results.map(function (result) { return (React.createElement(Stack, { key: result.id, tokens: { childrenGap: 2 }, styles: { root: { padding: '8px', backgroundColor: '#faf9f8', borderRadius: '4px' } } },
546
- React.createElement("div", { style: { fontWeight: 600 } }, result.data.Title || '(No Title)'),
547
- React.createElement(Label, null,
548
- result.data.FileType,
549
- " | ",
550
- result.data.Author),
551
- React.createElement("a", { href: result.data.Path, target: "_blank", rel: "noopener noreferrer", style: { fontSize: '11px' } }, result.data.Path))); })) : (React.createElement(Label, null, "Click \"Search All Content\" to see results.")))),
552
- React.createElement(Label, null,
553
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
554
- "Faceted search with FileType and Author refiners. Click to filter/toggle.")));
555
- };
556
- /**
557
- * Example 6: Search Suggestions (Autocomplete)
558
- */
559
- var PnPSearchSuggestionsExample = function () {
560
- var _a = React.useState(''), query = _a[0], setQuery = _a[1];
561
- var _b = React.useState([]), suggestions = _b[0], setSuggestions = _b[1];
562
- var suggest = useSPFxPnPSearch().suggest;
563
- // Track if component is mounted to prevent state updates after unmount
564
- var mountedRef = React.useRef(true);
565
- // Cleanup on unmount
566
- React.useEffect(function () {
567
- mountedRef.current = true;
568
- return function () {
569
- mountedRef.current = false;
570
- };
571
- }, []);
572
- var handleSuggest = React.useCallback(function (value) { return __awaiter(void 0, void 0, void 0, function () {
573
- var results, err_6;
574
- return __generator(this, function (_a) {
575
- switch (_a.label) {
576
- case 0:
577
- if (!value || value.length < 2) {
578
- if (mountedRef.current) {
579
- setSuggestions([]);
580
- }
581
- return [2 /*return*/];
582
- }
583
- _a.label = 1;
584
- case 1:
585
- _a.trys.push([1, 3, , 4]);
586
- return [4 /*yield*/, suggest(value)];
587
- case 2:
588
- results = _a.sent();
589
- if (mountedRef.current) {
590
- setSuggestions(results);
591
- }
592
- return [3 /*break*/, 4];
593
- case 3:
594
- err_6 = _a.sent();
595
- console.error('[PnPSearchSuggestions] Error:', err_6);
596
- if (mountedRef.current) {
597
- setSuggestions([]);
598
- }
599
- return [3 /*break*/, 4];
600
- case 4: return [2 /*return*/];
601
- }
602
- });
603
- }); }, [suggest]);
604
- // Debounced suggest with proper cleanup
605
- var debouncedSuggest = React.useMemo(function () {
606
- var timeoutId;
607
- // Return debounced function
608
- var debounced = function (value) {
609
- if (timeoutId !== undefined) {
610
- clearTimeout(timeoutId);
611
- }
612
- timeoutId = window.setTimeout(function () { return handleSuggest(value); }, 300);
613
- };
614
- // Cleanup function stored in the debounced function
615
- debounced.cancel = function () {
616
- if (timeoutId !== undefined) {
617
- clearTimeout(timeoutId);
618
- timeoutId = undefined;
619
- }
620
- };
621
- return debounced;
622
- }, [handleSuggest]);
623
- // Cleanup timeout on unmount
624
- React.useEffect(function () {
625
- return function () {
626
- var _a;
627
- (_a = debouncedSuggest.cancel) === null || _a === void 0 ? void 0 : _a.call(debouncedSuggest);
628
- };
629
- }, [debouncedSuggest]);
630
- var handleQueryChange = React.useCallback(function (value) {
631
- setQuery(value);
632
- debouncedSuggest(value);
633
- }, [debouncedSuggest]);
634
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
635
- React.createElement("h3", null,
636
- React.createElement(Icon, { iconName: "SearchBookmark", style: { marginRight: '8px' } }),
637
- "Example 4: Search Suggestions (Autocomplete)"),
638
- React.createElement(Separator, null),
639
- React.createElement(TextField, { label: "Search with Autocomplete", value: query, onChange: function (_, newValue) { return handleQueryChange(newValue !== null && newValue !== void 0 ? newValue : ''); }, placeholder: "Type at least 2 characters..." }),
640
- suggestions.length > 0 ? (React.createElement(Stack, { tokens: { childrenGap: 2 }, styles: { root: { padding: '8px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
641
- React.createElement(Label, null,
642
- "Suggestions (",
643
- suggestions.length,
644
- "):"),
645
- suggestions.map(function (s, idx) { return (React.createElement("div", { key: idx, style: { padding: '6px', backgroundColor: '#fff', borderRadius: '2px', cursor: 'pointer' }, onClick: function () { return setQuery(s); } }, s)); }))) : query.length >= 2 ? (React.createElement(MessageBar, { messageBarType: MessageBarType.info }, "No suggestions available. This is normal in dev/test environments where there isn't enough indexed content. Try in a production environment with more search activity.")) : null,
646
- React.createElement(Label, null,
647
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
648
- "Real-time autocomplete with 300ms debounce. Requires indexed content and search activity.")));
649
- };
650
- /**
651
- * Example 7: useSPFxPnPList - CRUD Operations
652
- */
653
- var PnPListExample = function () {
654
- var _a = React.useState(''), listTitle = _a[0], setListTitle = _a[1];
655
- var _b = React.useState(''), newTitle = _b[0], setNewTitle = _b[1];
656
- var _c = React.useState(null), editingId = _c[0], setEditingId = _c[1];
657
- var _d = React.useState(''), editTitle = _d[0], setEditTitle = _d[1];
658
- var _e = useSPFxPnPList(listTitle, { pageSize: 10 }), query = _e.query, items = _e.items, loading = _e.loading, error = _e.error, isEmpty = _e.isEmpty, hasMore = _e.hasMore, loadMore = _e.loadMore, clearError = _e.clearError, create = _e.create, update = _e.update, remove = _e.remove;
659
- var handleLoadList = React.useCallback(function () {
660
- query(function (q) { return q.select('Id', 'Title').orderBy('Id', false); }).catch(function (err) { return console.error('Load error:', err); });
661
- }, [query]);
662
- var handleCreate = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
663
- var err_7;
664
- return __generator(this, function (_a) {
665
- switch (_a.label) {
666
- case 0:
667
- if (!newTitle || !listTitle)
668
- return [2 /*return*/];
669
- _a.label = 1;
670
- case 1:
671
- _a.trys.push([1, 3, , 4]);
672
- return [4 /*yield*/, create({ Title: newTitle })];
673
- case 2:
674
- _a.sent();
675
- setNewTitle('');
676
- return [3 /*break*/, 4];
677
- case 3:
678
- err_7 = _a.sent();
679
- console.error('Create error:', err_7);
680
- return [3 /*break*/, 4];
681
- case 4: return [2 /*return*/];
682
- }
683
- });
684
- }); }, [create, newTitle, listTitle]);
685
- var handleUpdate = React.useCallback(function (id) { return __awaiter(void 0, void 0, void 0, function () {
686
- var err_8;
687
- return __generator(this, function (_a) {
688
- switch (_a.label) {
689
- case 0:
690
- if (!editTitle)
691
- return [2 /*return*/];
692
- _a.label = 1;
693
- case 1:
694
- _a.trys.push([1, 3, , 4]);
695
- return [4 /*yield*/, update(id, { Title: editTitle })];
696
- case 2:
697
- _a.sent();
698
- setEditingId(null);
699
- setEditTitle('');
700
- return [3 /*break*/, 4];
701
- case 3:
702
- err_8 = _a.sent();
703
- console.error('Update error:', err_8);
704
- return [3 /*break*/, 4];
705
- case 4: return [2 /*return*/];
706
- }
707
- });
708
- }); }, [update, editTitle]);
709
- var handleDelete = React.useCallback(function (id) { return __awaiter(void 0, void 0, void 0, function () {
710
- var err_9;
711
- return __generator(this, function (_a) {
712
- switch (_a.label) {
713
- case 0:
714
- if (!confirm('Delete this item?'))
715
- return [2 /*return*/];
716
- _a.label = 1;
717
- case 1:
718
- _a.trys.push([1, 3, , 4]);
719
- return [4 /*yield*/, remove(id)];
720
- case 2:
721
- _a.sent();
722
- return [3 /*break*/, 4];
723
- case 3:
724
- err_9 = _a.sent();
725
- console.error('Delete error:', err_9);
726
- return [3 /*break*/, 4];
727
- case 4: return [2 /*return*/];
728
- }
729
- });
730
- }); }, [remove]);
731
- return (React.createElement(Stack, { tokens: { childrenGap: 10 }, styles: { root: { padding: '16px', border: '1px solid #edebe9', borderRadius: '4px' } } },
732
- React.createElement("h3", null,
733
- React.createElement(Icon, { iconName: "BulletedList", style: { marginRight: '8px' } }),
734
- "Example 3: useSPFxPnPList - CRUD Operations"),
735
- React.createElement(Separator, null),
736
- React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 6 } },
737
- React.createElement(TextField, { label: "List Title", value: listTitle, onChange: function (_, newValue) { return setListTitle(newValue !== null && newValue !== void 0 ? newValue : ''); }, placeholder: "e.g., Site Pages", styles: { root: { flexGrow: 1 } } }),
738
- React.createElement(PrimaryButton, { text: "Load", onClick: handleLoadList, disabled: !listTitle || loading, styles: { root: { marginTop: '28px' } } })),
739
- error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error, onDismiss: clearError }, error.message)),
740
- listTitle && (React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 6 }, styles: { root: { padding: '8px', backgroundColor: '#f3f2f1', borderRadius: '4px' } } },
741
- React.createElement(TextField, { value: newTitle, onChange: function (_, newValue) { return setNewTitle(newValue !== null && newValue !== void 0 ? newValue : ''); }, placeholder: "New item title...", styles: { root: { flexGrow: 1 } } }),
742
- React.createElement(PrimaryButton, { text: "Create", onClick: handleCreate, disabled: !newTitle || loading }))),
743
- loading && React.createElement(MessageBar, null, "Loading..."),
744
- isEmpty && !loading && React.createElement(MessageBar, null, "No items found."),
745
- items.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 3 } },
746
- React.createElement(Label, null,
747
- "Items (",
748
- items.length,
749
- "):"),
750
- items.map(function (item) { return (React.createElement(Stack, { key: item.Id, horizontal: true, tokens: { childrenGap: 6 }, styles: { root: { padding: '6px', backgroundColor: '#faf9f8', borderRadius: '4px' } } }, editingId === item.Id ? (React.createElement(React.Fragment, null,
751
- React.createElement(TextField, { value: editTitle, onChange: function (_, v) { return setEditTitle(v !== null && v !== void 0 ? v : ''); }, styles: { root: { flexGrow: 1 } } }),
752
- React.createElement(DefaultButton, { text: "Save", onClick: function () { return handleUpdate(item.Id); } }),
753
- React.createElement(DefaultButton, { text: "Cancel", onClick: function () { setEditingId(null); setEditTitle(''); } }))) : (React.createElement(React.Fragment, null,
754
- React.createElement("div", { style: { flexGrow: 1 } },
755
- "#",
756
- item.Id,
757
- " - ",
758
- item.Title),
759
- React.createElement(DefaultButton, { text: "Edit", onClick: function () { setEditingId(item.Id); setEditTitle(item.Title); } }),
760
- React.createElement(DefaultButton, { text: "Delete", onClick: function () { return handleDelete(item.Id); } }))))); }),
761
- hasMore && React.createElement(PrimaryButton, { text: "Load More", onClick: loadMore, disabled: loading }))),
762
- React.createElement(Label, null,
763
- React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
764
- "Complete CRUD with auto-refetch. Try with \"Site Pages\" or \"Documents\".")));
765
- };
766
54
  // Helper function to safely stringify objects with circular references
767
55
  var safeStringify = function (obj, indent) {
768
56
  if (indent === void 0) { indent = 2; }
@@ -823,10 +111,8 @@ var SpFxReactToolkitTest = function () {
823
111
  var spHttpClient = useSPFxSPHttpClient();
824
112
  var msGraphClient = useSPFxMSGraphClient();
825
113
  var aadHttpClient = useSPFxAadHttpClient();
826
- // OneDrive AppData hook (using instance id as folder for isolation)
827
- var oneDriveData = useSPFxOneDriveAppData('test-data.json', id, // Use instance ID as folder for multi-instance support
828
- false // Manual load for demo purposes
829
- );
114
+ // OneDrive AppData hook (using hook name as folder for demo)
115
+ var oneDriveData = useSPFxOneDriveAppData('test-data.json', { autoFetch: false, createIfMissing: true, defaultValue: { message: '', counter: 0, timestamp: 0 }, folder: 'useSPFxOneDriveAppData' });
830
116
  // Tenant Property hook (tenant-wide configuration)
831
117
  var tenantVersion = useSPFxTenantProperty('spfx-toolkit-test-version', false);
832
118
  var tenantCounter = useSPFxTenantProperty('spfx-toolkit-test-counter', false);
@@ -918,7 +204,7 @@ var SpFxReactToolkitTest = function () {
918
204
  });
919
205
  }); }, [oneDriveData]);
920
206
  var handleSaveOneDrive = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
921
- var newData, error_3;
207
+ var newData, error_1;
922
208
  var _a, _b;
923
209
  return __generator(this, function (_c) {
924
210
  switch (_c.label) {
@@ -938,8 +224,8 @@ var SpFxReactToolkitTest = function () {
938
224
  setTimeout(function () { return setShowMessage(false); }, 3000);
939
225
  return [3 /*break*/, 3];
940
226
  case 2:
941
- error_3 = _c.sent();
942
- setMessageText("Save failed: ".concat(error_3 instanceof Error ? error_3.message : 'Unknown error'));
227
+ error_1 = _c.sent();
228
+ setMessageText("Save failed: ".concat(error_1 instanceof Error ? error_1.message : 'Unknown error'));
943
229
  setShowMessage(true);
944
230
  setTimeout(function () { return setShowMessage(false); }, 5000);
945
231
  return [3 /*break*/, 3];
@@ -948,7 +234,7 @@ var SpFxReactToolkitTest = function () {
948
234
  });
949
235
  }); }, [oneDriveMessage, oneDriveData]);
950
236
  var handleLoadTenantProperty = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
951
- var error_4;
237
+ var error_2;
952
238
  return __generator(this, function (_a) {
953
239
  switch (_a.label) {
954
240
  case 0:
@@ -964,8 +250,8 @@ var SpFxReactToolkitTest = function () {
964
250
  setTimeout(function () { return setShowMessage(false); }, 3000);
965
251
  return [3 /*break*/, 3];
966
252
  case 2:
967
- error_4 = _a.sent();
968
- setMessageText("Load failed: ".concat(error_4 instanceof Error ? error_4.message : 'Unknown error'));
253
+ error_2 = _a.sent();
254
+ setMessageText("Load failed: ".concat(error_2 instanceof Error ? error_2.message : 'Unknown error'));
969
255
  setShowMessage(true);
970
256
  setTimeout(function () { return setShowMessage(false); }, 5000);
971
257
  return [3 /*break*/, 3];
@@ -974,7 +260,7 @@ var SpFxReactToolkitTest = function () {
974
260
  });
975
261
  }); }, [tenantVersion, tenantCounter]);
976
262
  var handleSaveTenantVersion = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
977
- var error_5;
263
+ var error_3;
978
264
  return __generator(this, function (_a) {
979
265
  switch (_a.label) {
980
266
  case 0:
@@ -996,8 +282,8 @@ var SpFxReactToolkitTest = function () {
996
282
  setTimeout(function () { return setShowMessage(false); }, 3000);
997
283
  return [3 /*break*/, 4];
998
284
  case 3:
999
- error_5 = _a.sent();
1000
- setMessageText("Save failed: ".concat(error_5 instanceof Error ? error_5.message : 'Unknown error'));
285
+ error_3 = _a.sent();
286
+ setMessageText("Save failed: ".concat(error_3 instanceof Error ? error_3.message : 'Unknown error'));
1001
287
  setShowMessage(true);
1002
288
  setTimeout(function () { return setShowMessage(false); }, 5000);
1003
289
  return [3 /*break*/, 4];
@@ -1006,7 +292,7 @@ var SpFxReactToolkitTest = function () {
1006
292
  });
1007
293
  }); }, [tenantVersionInput, tenantVersion]);
1008
294
  var handleIncrementTenantCounter = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
1009
- var newValue, error_6;
295
+ var newValue, error_4;
1010
296
  var _a;
1011
297
  return __generator(this, function (_b) {
1012
298
  switch (_b.label) {
@@ -1029,8 +315,8 @@ var SpFxReactToolkitTest = function () {
1029
315
  setTimeout(function () { return setShowMessage(false); }, 3000);
1030
316
  return [3 /*break*/, 4];
1031
317
  case 3:
1032
- error_6 = _b.sent();
1033
- setMessageText("Increment failed: ".concat(error_6 instanceof Error ? error_6.message : 'Unknown error'));
318
+ error_4 = _b.sent();
319
+ setMessageText("Increment failed: ".concat(error_4 instanceof Error ? error_4.message : 'Unknown error'));
1034
320
  setShowMessage(true);
1035
321
  setTimeout(function () { return setShowMessage(false); }, 5000);
1036
322
  return [3 /*break*/, 4];
@@ -1039,7 +325,7 @@ var SpFxReactToolkitTest = function () {
1039
325
  });
1040
326
  }); }, [tenantCounter]);
1041
327
  var handleRemoveTenantProperty = React.useCallback(function (propertyName) { return __awaiter(void 0, void 0, void 0, function () {
1042
- var hook, error_7;
328
+ var hook, error_5;
1043
329
  return __generator(this, function (_a) {
1044
330
  switch (_a.label) {
1045
331
  case 0:
@@ -1064,8 +350,8 @@ var SpFxReactToolkitTest = function () {
1064
350
  setTimeout(function () { return setShowMessage(false); }, 3000);
1065
351
  return [3 /*break*/, 4];
1066
352
  case 3:
1067
- error_7 = _a.sent();
1068
- setMessageText("Remove failed: ".concat(error_7 instanceof Error ? error_7.message : 'Unknown error'));
353
+ error_5 = _a.sent();
354
+ setMessageText("Remove failed: ".concat(error_5 instanceof Error ? error_5.message : 'Unknown error'));
1069
355
  setShowMessage(true);
1070
356
  setTimeout(function () { return setShowMessage(false); }, 5000);
1071
357
  return [3 /*break*/, 4];
@@ -1274,9 +560,7 @@ var SpFxReactToolkitTest = function () {
1274
560
  React.createElement(PrimaryButton, { text: oneDriveData.isWriting ? 'Saving...' : 'Save to OneDrive', onClick: handleSaveOneDrive, disabled: !oneDriveMessage || oneDriveData.isWriting || oneDriveData.isLoading, iconProps: { iconName: 'CloudUpload' } })),
1275
561
  React.createElement(Label, null,
1276
562
  React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
1277
- "Data is stored in your OneDrive (appRoot:/",
1278
- id,
1279
- "/test-data.json). Each WebPart instance has its own file."),
563
+ "Data is stored in your OneDrive (appRoot:/useSPFxOneDriveAppData/test-data.json)."),
1280
564
  React.createElement(Label, null,
1281
565
  React.createElement(Icon, { iconName: "Warning", style: { marginRight: '4px', color: '#d83b01' } }),
1282
566
  "Requires Microsoft Graph permissions: Files.ReadWrite or Files.ReadWrite.AppFolder")),
@@ -1427,22 +711,22 @@ var SpFxReactToolkitTest = function () {
1427
711
  "This hook provides access to the generic HttpClient for calling external APIs (non-SharePoint). For SharePoint REST API calls, use ",
1428
712
  React.createElement("strong", null, "useSPFxSPHttpClient"),
1429
713
  " instead."),
1430
- React.createElement(HttpClientExample, null))),
714
+ React.createElement(HttpClientDemo, null))),
1431
715
  React.createElement(PivotItem, { headerText: "PnPjs", itemIcon: "CloudDownload" },
1432
716
  React.createElement(Stack, { tokens: { childrenGap: 20 }, styles: { root: { marginTop: '16px' } } },
1433
- React.createElement(PnPContextExample, null),
1434
- React.createElement(PnPOperationsExample, null),
1435
- React.createElement(PnPListExample, null))),
717
+ React.createElement(PnPContextDemo, null),
718
+ React.createElement(PnPOperationsDemo, null),
719
+ React.createElement(PnPListDemo, null))),
1436
720
  React.createElement(PivotItem, { headerText: "Search", itemIcon: "Search" },
1437
721
  React.createElement(Stack, { tokens: { childrenGap: 20 }, styles: { root: { marginTop: '16px' } } },
1438
722
  React.createElement(MessageBar, { messageBarType: MessageBarType.info },
1439
723
  React.createElement("strong", null, "useSPFxPnPSearch Hook Examples"),
1440
724
  React.createElement("br", null),
1441
725
  "These examples demonstrate SharePoint Search capabilities using the native PnPjs SearchQueryBuilder API."),
1442
- React.createElement(PnPSearchBasicExample, null),
1443
- React.createElement(PnPSearchAdvancedExample, null),
1444
- React.createElement(PnPSearchRefinersExample, null),
1445
- React.createElement(PnPSearchSuggestionsExample, null))))));
726
+ React.createElement(PnPSearchBasicDemo, null),
727
+ React.createElement(PnPSearchAdvancedDemo, null),
728
+ React.createElement(PnPSearchRefinersDemo, null),
729
+ React.createElement(PnPSearchSuggestionsDemo, null))))));
1446
730
  };
1447
731
  export default SpFxReactToolkitTest;
1448
732
  //# sourceMappingURL=SpFxReactToolkitTest.js.map