@apvee/spfx-react-toolkit 1.2.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core/atoms.internal.js +1 -1
- package/lib/core/atoms.internal.js.map +1 -1
- package/lib/core/context.internal.js +2 -2
- package/lib/core/context.internal.js.map +1 -1
- package/lib/core/provider-base.internal.js +29 -29
- package/lib/core/provider-base.internal.js.map +1 -1
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.d.ts +14 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.d.ts.map +1 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js +20 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.js.map +1 -0
- package/lib/extensions/spFxReactToolkitTest/SpFxReactToolkitTestApplicationCustomizer.manifest.json +17 -0
- package/lib/extensions/spFxReactToolkitTest/loc/en-us.js +5 -0
- package/lib/hooks/index.d.ts +1 -0
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/index.js +1 -0
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/useAppCatalogUrl.internal.d.ts +26 -0
- package/lib/hooks/useAppCatalogUrl.internal.d.ts.map +1 -0
- package/lib/hooks/useAppCatalogUrl.internal.js +72 -0
- package/lib/hooks/useAppCatalogUrl.internal.js.map +1 -0
- package/lib/hooks/useAsyncInvoke.internal.js +27 -75
- package/lib/hooks/useAsyncInvoke.internal.js.map +1 -1
- package/lib/hooks/useSPFxAadHttpClient.d.ts +46 -0
- package/lib/hooks/useSPFxAadHttpClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxAadHttpClient.js +65 -20
- package/lib/hooks/useSPFxAadHttpClient.js.map +1 -1
- package/lib/hooks/useSPFxContainerInfo.js +5 -5
- package/lib/hooks/useSPFxContainerInfo.js.map +1 -1
- package/lib/hooks/useSPFxContainerSize.js +9 -10
- package/lib/hooks/useSPFxContainerSize.js.map +1 -1
- package/lib/hooks/useSPFxCorrelationInfo.js +6 -7
- package/lib/hooks/useSPFxCorrelationInfo.js.map +1 -1
- package/lib/hooks/useSPFxCrossSitePermissions.js +48 -58
- package/lib/hooks/useSPFxCrossSitePermissions.js.map +1 -1
- package/lib/hooks/useSPFxDisplayMode.js +8 -8
- package/lib/hooks/useSPFxDisplayMode.js.map +1 -1
- package/lib/hooks/useSPFxEnvironmentInfo.js +17 -18
- package/lib/hooks/useSPFxEnvironmentInfo.js.map +1 -1
- package/lib/hooks/useSPFxFluent9ThemeInfo.js +4 -4
- package/lib/hooks/useSPFxFluent9ThemeInfo.js.map +1 -1
- package/lib/hooks/useSPFxHttpClient.d.ts +18 -2
- package/lib/hooks/useSPFxHttpClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxHttpClient.js +19 -9
- package/lib/hooks/useSPFxHttpClient.js.map +1 -1
- package/lib/hooks/useSPFxHubSiteInfo.js +21 -24
- package/lib/hooks/useSPFxHubSiteInfo.js.map +1 -1
- package/lib/hooks/useSPFxInstanceInfo.js +2 -2
- package/lib/hooks/useSPFxInstanceInfo.js.map +1 -1
- package/lib/hooks/useSPFxListInfo.js +8 -9
- package/lib/hooks/useSPFxListInfo.js.map +1 -1
- package/lib/hooks/useSPFxLocaleInfo.js +10 -10
- package/lib/hooks/useSPFxLocaleInfo.js.map +1 -1
- package/lib/hooks/useSPFxLogger.js +26 -26
- package/lib/hooks/useSPFxLogger.js.map +1 -1
- package/lib/hooks/useSPFxMSGraphClient.d.ts +50 -3
- package/lib/hooks/useSPFxMSGraphClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxMSGraphClient.js +68 -15
- package/lib/hooks/useSPFxMSGraphClient.js.map +1 -1
- package/lib/hooks/useSPFxOneDriveAppData.d.ts +0 -1
- package/lib/hooks/useSPFxOneDriveAppData.d.ts.map +1 -1
- package/lib/hooks/useSPFxOneDriveAppData.js +420 -230
- package/lib/hooks/useSPFxOneDriveAppData.js.map +1 -1
- package/lib/hooks/useSPFxPageContext.js +2 -2
- package/lib/hooks/useSPFxPageContext.js.map +1 -1
- package/lib/hooks/useSPFxPageType.js +19 -20
- package/lib/hooks/useSPFxPageType.js.map +1 -1
- package/lib/hooks/useSPFxPerformance.js +33 -87
- package/lib/hooks/useSPFxPerformance.js.map +1 -1
- package/lib/hooks/useSPFxPermissions.js +14 -15
- package/lib/hooks/useSPFxPermissions.js.map +1 -1
- package/lib/hooks/useSPFxPnP.js +62 -119
- package/lib/hooks/useSPFxPnP.js.map +1 -1
- package/lib/hooks/useSPFxPnPContext.js +22 -25
- package/lib/hooks/useSPFxPnPContext.js.map +1 -1
- package/lib/hooks/useSPFxPnPList.js +307 -451
- package/lib/hooks/useSPFxPnPList.js.map +1 -1
- package/lib/hooks/useSPFxPnPSearch.js +262 -353
- package/lib/hooks/useSPFxPnPSearch.js.map +1 -1
- package/lib/hooks/useSPFxProperties.js +12 -20
- package/lib/hooks/useSPFxProperties.js.map +1 -1
- package/lib/hooks/useSPFxSPHttpClient.d.ts +18 -2
- package/lib/hooks/useSPFxSPHttpClient.d.ts.map +1 -1
- package/lib/hooks/useSPFxSPHttpClient.js +28 -18
- package/lib/hooks/useSPFxSPHttpClient.js.map +1 -1
- package/lib/hooks/useSPFxServiceScope.js +6 -6
- package/lib/hooks/useSPFxServiceScope.js.map +1 -1
- package/lib/hooks/useSPFxSiteInfo.js +7 -8
- package/lib/hooks/useSPFxSiteInfo.js.map +1 -1
- package/lib/hooks/useSPFxStorage.js +22 -22
- package/lib/hooks/useSPFxStorage.js.map +1 -1
- package/lib/hooks/useSPFxTeams.js +37 -92
- package/lib/hooks/useSPFxTeams.js.map +1 -1
- package/lib/hooks/useSPFxTenantKeyValueStore.d.ts +252 -0
- package/lib/hooks/useSPFxTenantKeyValueStore.d.ts.map +1 -0
- package/lib/hooks/useSPFxTenantKeyValueStore.js +572 -0
- package/lib/hooks/useSPFxTenantKeyValueStore.js.map +1 -0
- package/lib/hooks/useSPFxTenantProperty.d.ts +23 -244
- package/lib/hooks/useSPFxTenantProperty.d.ts.map +1 -1
- package/lib/hooks/useSPFxTenantProperty.js +85 -559
- package/lib/hooks/useSPFxTenantProperty.js.map +1 -1
- package/lib/hooks/useSPFxUserInfo.js +3 -4
- package/lib/hooks/useSPFxUserInfo.js.map +1 -1
- package/lib/hooks/useSPFxUserPhoto.js +76 -123
- package/lib/hooks/useSPFxUserPhoto.js.map +1 -1
- package/lib/utils/resize-observer.internal.js +6 -7
- package/lib/utils/resize-observer.internal.js.map +1 -1
- package/lib/utils/theme-subscription.internal.js +8 -8
- package/lib/utils/theme-subscription.internal.js.map +1 -1
- package/lib/utils/type-guards.internal.js +6 -6
- package/lib/utils/type-guards.internal.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js +12 -37
- package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js +279 -342
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js +26 -86
- package/lib/webparts/spFxReactToolkitTest/components/demos/HttpClientDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js +53 -113
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPContextDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js +49 -121
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPListDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js +44 -103
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPOperationsDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js +15 -15
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchAdvancedDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js +18 -66
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchBasicDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js +9 -9
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchRefinersDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js +37 -86
- package/lib/webparts/spFxReactToolkitTest/components/demos/PnPSearchSuggestionsDemo.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js +6 -9
- package/lib/webparts/spFxReactToolkitTest/components/shared/InfoRow.js.map +1 -1
- package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js +3 -6
- package/lib/webparts/spFxReactToolkitTest/components/shared/StatusBadge.js.map +1 -1
- package/package.json +8 -6
|
@@ -1,61 +1,15 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
-
function step(op) {
|
|
15
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
-
switch (op[0]) {
|
|
20
|
-
case 0: case 1: t = op; break;
|
|
21
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
-
default:
|
|
25
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
-
if (t[2]) _.ops.pop();
|
|
30
|
-
_.trys.pop(); continue;
|
|
31
|
-
}
|
|
32
|
-
op = body.call(thisArg, _);
|
|
33
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
38
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
39
|
-
if (ar || !(i in from)) {
|
|
40
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
41
|
-
ar[i] = from[i];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
45
|
-
};
|
|
46
1
|
import * as React from 'react';
|
|
47
2
|
import styles from './SpFxReactToolkitTest.module.scss';
|
|
48
3
|
import { Stack, Pivot, PivotItem, TextField, PrimaryButton, DefaultButton, MessageBar, MessageBarType, Separator, Label, Icon, } from '@fluentui/react';
|
|
49
4
|
import { InfoRow, StatusBadge } from './shared';
|
|
50
5
|
import { HttpClientDemo, PnPContextDemo, PnPOperationsDemo, PnPListDemo, PnPSearchBasicDemo, PnPSearchAdvancedDemo, PnPSearchRefinersDemo, PnPSearchSuggestionsDemo, } from './demos';
|
|
51
6
|
// 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';
|
|
7
|
+
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, useSPFxTenantKeyValueStore, useSPFxUserPhoto, } from '../../../hooks';
|
|
53
8
|
import { SPPermission } from '@microsoft/sp-page-context';
|
|
54
9
|
// Helper function to safely stringify objects with circular references
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return JSON.stringify(obj, function (key, value) {
|
|
10
|
+
const safeStringify = (obj, indent = 2) => {
|
|
11
|
+
const seen = new WeakSet();
|
|
12
|
+
return JSON.stringify(obj, (key, value) => {
|
|
59
13
|
// Skip private properties and service scopes to avoid circular references
|
|
60
14
|
if (typeof key === 'string' && (key.indexOf('_') === 0 || key === 'serviceScope' || key === 'service')) {
|
|
61
15
|
return '[Circular/Private]';
|
|
@@ -69,300 +23,254 @@ var safeStringify = function (obj, indent) {
|
|
|
69
23
|
return value;
|
|
70
24
|
}, indent);
|
|
71
25
|
};
|
|
72
|
-
|
|
73
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
26
|
+
const SpFxReactToolkitTest = () => {
|
|
74
27
|
// Core Properties & Display
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
28
|
+
const { properties, setProperties } = useSPFxProperties();
|
|
29
|
+
const { isEdit } = useSPFxDisplayMode();
|
|
30
|
+
const { id, kind } = useSPFxInstanceInfo();
|
|
78
31
|
// Theme & Environment
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
32
|
+
const theme = useSPFxThemeInfo();
|
|
33
|
+
const fluent9ThemeInfo = useSPFxFluent9ThemeInfo();
|
|
34
|
+
const { type: envType } = useSPFxEnvironmentInfo();
|
|
35
|
+
const isDarkTheme = theme?.isInverted ?? false;
|
|
83
36
|
// User & Site Info
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
37
|
+
const { displayName } = useSPFxUserInfo();
|
|
38
|
+
const { title: siteTitle, webUrl, siteClassification } = useSPFxSiteInfo();
|
|
39
|
+
const localeInfo = useSPFxLocaleInfo();
|
|
87
40
|
// Teams Context
|
|
88
|
-
|
|
41
|
+
const { supported: hasTeamsContext, theme: teamsTheme } = useSPFxTeams();
|
|
89
42
|
// Page Context
|
|
90
|
-
|
|
91
|
-
|
|
43
|
+
const pageContext = useSPFxPageContext();
|
|
44
|
+
const pageTypeInfo = useSPFxPageType();
|
|
92
45
|
// List & Hub Info (can be undefined)
|
|
93
|
-
|
|
94
|
-
|
|
46
|
+
const listInfo = useSPFxListInfo();
|
|
47
|
+
const hubInfo = useSPFxHubSiteInfo();
|
|
95
48
|
// Container & Performance
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
49
|
+
const containerSize = useSPFxContainerSize();
|
|
50
|
+
const containerInfo = useSPFxContainerInfo();
|
|
51
|
+
const performance = useSPFxPerformance();
|
|
99
52
|
// Permissions
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
53
|
+
const { hasWebPermission } = useSPFxPermissions();
|
|
54
|
+
const canManageWeb = hasWebPermission(SPPermission.manageWeb);
|
|
55
|
+
const canManageLists = hasWebPermission(SPPermission.manageLists);
|
|
103
56
|
// Storage
|
|
104
|
-
|
|
105
|
-
|
|
57
|
+
const sessionStorage = useSPFxSessionStorage('demo-session-key', '');
|
|
58
|
+
const localStorage = useSPFxLocalStorage('demo-local-key', '');
|
|
106
59
|
// Advanced
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
60
|
+
const correlationInfo = useSPFxCorrelationInfo();
|
|
61
|
+
const logger = useSPFxLogger();
|
|
62
|
+
const serviceScope = useSPFxServiceScope();
|
|
110
63
|
// HTTP Clients
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// OneDrive AppData hook (using
|
|
115
|
-
|
|
116
|
-
false // Manual load for demo purposes
|
|
117
|
-
);
|
|
64
|
+
const spHttpClient = useSPFxSPHttpClient();
|
|
65
|
+
const msGraphClient = useSPFxMSGraphClient();
|
|
66
|
+
const aadHttpClient = useSPFxAadHttpClient();
|
|
67
|
+
// OneDrive AppData hook (using hook name as folder for demo)
|
|
68
|
+
const oneDriveData = useSPFxOneDriveAppData('test-data.json', { autoFetch: false, createIfMissing: true, defaultValue: { message: '', counter: 0, timestamp: 0 }, folder: 'useSPFxOneDriveAppData' });
|
|
118
69
|
// Tenant Property hook (tenant-wide configuration)
|
|
119
|
-
|
|
120
|
-
|
|
70
|
+
const tenantVersion = useSPFxTenantProperty('spfx-toolkit-test-version', false);
|
|
71
|
+
const tenantCounter = useSPFxTenantProperty('spfx-toolkit-test-counter', false);
|
|
72
|
+
// Tenant Key-Value Store hook (REST-based CRUD)
|
|
73
|
+
const tenantKVStore = useSPFxTenantKeyValueStore();
|
|
121
74
|
// User Photo hook (current user profile photo)
|
|
122
|
-
|
|
75
|
+
const userPhoto = useSPFxUserPhoto();
|
|
123
76
|
// Local state for interactive demos
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
77
|
+
const [descriptionInput, setDescriptionInput] = React.useState(properties?.description ?? '');
|
|
78
|
+
const [sessionStorageInput, setSessionStorageInput] = React.useState('');
|
|
79
|
+
const [localStorageInput, setLocalStorageInput] = React.useState('');
|
|
80
|
+
const [oneDriveMessage, setOneDriveMessage] = React.useState('');
|
|
81
|
+
const [tenantVersionInput, setTenantVersionInput] = React.useState('');
|
|
82
|
+
const [showMessage, setShowMessage] = React.useState(false);
|
|
83
|
+
const [messageText, setMessageText] = React.useState('');
|
|
84
|
+
const [performanceResult, setPerformanceResult] = React.useState('');
|
|
85
|
+
const [logMessages, setLogMessages] = React.useState([]);
|
|
86
|
+
const [crossSiteUrl, setCrossSiteUrl] = React.useState(undefined);
|
|
87
|
+
// Tenant Key-Value Store demo state
|
|
88
|
+
const [kvStoreKey, setKvStoreKey] = React.useState('');
|
|
89
|
+
const [kvStoreValue, setKvStoreValue] = React.useState('');
|
|
90
|
+
const [kvStoreDescription, setKvStoreDescription] = React.useState('');
|
|
91
|
+
const [kvStoreItems, setKvStoreItems] = React.useState([]);
|
|
92
|
+
const [kvStoreResult, setKvStoreResult] = React.useState('');
|
|
134
93
|
// Cross-site permissions (fetch only when URL is set)
|
|
135
|
-
|
|
94
|
+
const crossSitePermissions = useSPFxCrossSitePermissions(crossSiteUrl);
|
|
136
95
|
// Sync descriptionInput when properties change
|
|
137
|
-
React.useEffect(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}, [properties === null || properties === void 0 ? void 0 : properties.description]);
|
|
96
|
+
React.useEffect(() => {
|
|
97
|
+
setDescriptionInput(properties?.description ?? '');
|
|
98
|
+
}, [properties?.description]);
|
|
141
99
|
// Handlers
|
|
142
|
-
|
|
100
|
+
const handleUpdateProperties = React.useCallback(() => {
|
|
143
101
|
setProperties({ description: descriptionInput });
|
|
144
102
|
setMessageText('Properties updated successfully!');
|
|
145
103
|
setShowMessage(true);
|
|
146
|
-
setTimeout(
|
|
104
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
147
105
|
}, [descriptionInput, setProperties]);
|
|
148
|
-
|
|
106
|
+
const handleSaveSessionStorage = React.useCallback(() => {
|
|
149
107
|
sessionStorage.setValue(sessionStorageInput);
|
|
150
108
|
setSessionStorageInput('');
|
|
151
109
|
setMessageText('Value saved to session storage!');
|
|
152
110
|
setShowMessage(true);
|
|
153
|
-
setTimeout(
|
|
111
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
154
112
|
}, [sessionStorageInput, sessionStorage]);
|
|
155
|
-
|
|
113
|
+
const handleSaveLocalStorage = React.useCallback(() => {
|
|
156
114
|
localStorage.setValue(localStorageInput);
|
|
157
115
|
setLocalStorageInput('');
|
|
158
116
|
setMessageText('Value saved to local storage!');
|
|
159
117
|
setShowMessage(true);
|
|
160
|
-
setTimeout(
|
|
118
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
161
119
|
}, [localStorageInput, localStorage]);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return __generator(this, function (_a) {
|
|
168
|
-
switch (_a.label) {
|
|
169
|
-
case 0:
|
|
170
|
-
// Simulate async operation
|
|
171
|
-
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 500); })];
|
|
172
|
-
case 1:
|
|
173
|
-
// Simulate async operation
|
|
174
|
-
_a.sent();
|
|
175
|
-
return [2 /*return*/, 'Test completed'];
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}); })];
|
|
179
|
-
case 1:
|
|
180
|
-
result = _a.sent();
|
|
181
|
-
setPerformanceResult("".concat(result.result, " in ").concat(result.durationMs.toFixed(2), "ms"));
|
|
182
|
-
return [2 /*return*/];
|
|
183
|
-
}
|
|
120
|
+
const handlePerformanceTest = React.useCallback(async () => {
|
|
121
|
+
const result = await performance.time('demo-test', async () => {
|
|
122
|
+
// Simulate async operation
|
|
123
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
124
|
+
return 'Test completed';
|
|
184
125
|
});
|
|
185
|
-
|
|
186
|
-
|
|
126
|
+
setPerformanceResult(`${result.result} in ${result.durationMs.toFixed(2)}ms`);
|
|
127
|
+
}, [performance]);
|
|
128
|
+
const handleLog = React.useCallback((level, message) => {
|
|
187
129
|
if (level === 'info')
|
|
188
130
|
logger.info(message);
|
|
189
131
|
else if (level === 'warning')
|
|
190
132
|
logger.warn(message);
|
|
191
133
|
else
|
|
192
134
|
logger.error(message);
|
|
193
|
-
setLogMessages(
|
|
135
|
+
setLogMessages(prev => [...prev.slice(-4), { level, message }]);
|
|
194
136
|
}, [logger]);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
_a.trys.push([1, 3, , 4]);
|
|
278
|
-
return [4 /*yield*/, tenantVersion.write(tenantVersionInput, 'Test version property from SPFx React Toolkit')];
|
|
279
|
-
case 2:
|
|
280
|
-
_a.sent();
|
|
281
|
-
setTenantVersionInput('');
|
|
282
|
-
setMessageText('Version saved to tenant properties!');
|
|
283
|
-
setShowMessage(true);
|
|
284
|
-
setTimeout(function () { return setShowMessage(false); }, 3000);
|
|
285
|
-
return [3 /*break*/, 4];
|
|
286
|
-
case 3:
|
|
287
|
-
error_3 = _a.sent();
|
|
288
|
-
setMessageText("Save failed: ".concat(error_3 instanceof Error ? error_3.message : 'Unknown error'));
|
|
289
|
-
setShowMessage(true);
|
|
290
|
-
setTimeout(function () { return setShowMessage(false); }, 5000);
|
|
291
|
-
return [3 /*break*/, 4];
|
|
292
|
-
case 4: return [2 /*return*/];
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
}); }, [tenantVersionInput, tenantVersion]);
|
|
296
|
-
var handleIncrementTenantCounter = React.useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
297
|
-
var newValue, error_4;
|
|
298
|
-
var _a;
|
|
299
|
-
return __generator(this, function (_b) {
|
|
300
|
-
switch (_b.label) {
|
|
301
|
-
case 0:
|
|
302
|
-
if (!tenantCounter.canWrite) {
|
|
303
|
-
setMessageText('Insufficient permissions to write tenant properties');
|
|
304
|
-
setShowMessage(true);
|
|
305
|
-
setTimeout(function () { return setShowMessage(false); }, 5000);
|
|
306
|
-
return [2 /*return*/];
|
|
307
|
-
}
|
|
308
|
-
_b.label = 1;
|
|
309
|
-
case 1:
|
|
310
|
-
_b.trys.push([1, 3, , 4]);
|
|
311
|
-
newValue = ((_a = tenantCounter.data) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
312
|
-
return [4 /*yield*/, tenantCounter.write(newValue, 'Test counter property from SPFx React Toolkit')];
|
|
313
|
-
case 2:
|
|
314
|
-
_b.sent();
|
|
315
|
-
setMessageText("Counter incremented to ".concat(newValue, "!"));
|
|
316
|
-
setShowMessage(true);
|
|
317
|
-
setTimeout(function () { return setShowMessage(false); }, 3000);
|
|
318
|
-
return [3 /*break*/, 4];
|
|
319
|
-
case 3:
|
|
320
|
-
error_4 = _b.sent();
|
|
321
|
-
setMessageText("Increment failed: ".concat(error_4 instanceof Error ? error_4.message : 'Unknown error'));
|
|
322
|
-
setShowMessage(true);
|
|
323
|
-
setTimeout(function () { return setShowMessage(false); }, 5000);
|
|
324
|
-
return [3 /*break*/, 4];
|
|
325
|
-
case 4: return [2 /*return*/];
|
|
137
|
+
const handleLoadOneDrive = React.useCallback(async () => {
|
|
138
|
+
await oneDriveData.load();
|
|
139
|
+
setMessageText('OneDrive load completed. Check status below (missing file sets isNotFound=true).');
|
|
140
|
+
setShowMessage(true);
|
|
141
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
142
|
+
}, [oneDriveData]);
|
|
143
|
+
const handleSaveOneDrive = React.useCallback(async () => {
|
|
144
|
+
try {
|
|
145
|
+
const newData = {
|
|
146
|
+
message: oneDriveMessage,
|
|
147
|
+
counter: (oneDriveData.data?.counter ?? 0) + 1,
|
|
148
|
+
timestamp: Date.now(),
|
|
149
|
+
};
|
|
150
|
+
await oneDriveData.write(newData);
|
|
151
|
+
setOneDriveMessage('');
|
|
152
|
+
setMessageText('Data saved to OneDrive successfully!');
|
|
153
|
+
setShowMessage(true);
|
|
154
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
setMessageText(`Save failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
158
|
+
setShowMessage(true);
|
|
159
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
160
|
+
}
|
|
161
|
+
}, [oneDriveMessage, oneDriveData]);
|
|
162
|
+
const handleLoadTenantProperty = React.useCallback(async () => {
|
|
163
|
+
try {
|
|
164
|
+
await Promise.all([
|
|
165
|
+
tenantVersion.load(),
|
|
166
|
+
tenantCounter.load()
|
|
167
|
+
]);
|
|
168
|
+
setMessageText('Tenant properties loaded successfully!');
|
|
169
|
+
setShowMessage(true);
|
|
170
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
setMessageText(`Load failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
174
|
+
setShowMessage(true);
|
|
175
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
176
|
+
}
|
|
177
|
+
}, [tenantVersion, tenantCounter]);
|
|
178
|
+
const handleSaveTenantVersion = React.useCallback(async () => {
|
|
179
|
+
setMessageText('Write operations are no longer supported via REST API. Use PowerShell instead.');
|
|
180
|
+
setShowMessage(true);
|
|
181
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
182
|
+
}, []);
|
|
183
|
+
const handleIncrementTenantCounter = React.useCallback(async () => {
|
|
184
|
+
setMessageText('Write operations are no longer supported via REST API. Use PowerShell instead.');
|
|
185
|
+
setShowMessage(true);
|
|
186
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
187
|
+
}, []);
|
|
188
|
+
const handleRemoveTenantProperty = React.useCallback(async (_propertyName) => {
|
|
189
|
+
setMessageText('Remove operations are no longer supported via REST API. Use PowerShell instead.');
|
|
190
|
+
setShowMessage(true);
|
|
191
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
192
|
+
}, []);
|
|
193
|
+
// Tenant Key-Value Store handlers
|
|
194
|
+
const handleKVStoreList = React.useCallback(async () => {
|
|
195
|
+
try {
|
|
196
|
+
const items = await tenantKVStore.list();
|
|
197
|
+
setKvStoreItems(items);
|
|
198
|
+
setMessageText(`Listed ${items.length} item(s) from tenant key-value store.`);
|
|
199
|
+
setShowMessage(true);
|
|
200
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
setMessageText(`List failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
204
|
+
setShowMessage(true);
|
|
205
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
206
|
+
}
|
|
207
|
+
}, [tenantKVStore]);
|
|
208
|
+
const handleKVStoreGet = React.useCallback(async () => {
|
|
209
|
+
if (!kvStoreKey) {
|
|
210
|
+
setMessageText('Please enter a key to look up.');
|
|
211
|
+
setShowMessage(true);
|
|
212
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
const item = await tenantKVStore.get(kvStoreKey);
|
|
217
|
+
if (item) {
|
|
218
|
+
setKvStoreResult(`Key: ${item.key}, Value: ${typeof item.value === 'object' ? JSON.stringify(item.value) : String(item.value)}${item.description ? `, Description: ${item.description}` : ''}`);
|
|
326
219
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
var handleRemoveTenantProperty = React.useCallback(function (propertyName) { return __awaiter(void 0, void 0, void 0, function () {
|
|
330
|
-
var hook, error_5;
|
|
331
|
-
return __generator(this, function (_a) {
|
|
332
|
-
switch (_a.label) {
|
|
333
|
-
case 0:
|
|
334
|
-
hook = propertyName === 'version' ? tenantVersion : tenantCounter;
|
|
335
|
-
if (!hook.canWrite) {
|
|
336
|
-
setMessageText('Insufficient permissions to remove tenant properties');
|
|
337
|
-
setShowMessage(true);
|
|
338
|
-
setTimeout(function () { return setShowMessage(false); }, 5000);
|
|
339
|
-
return [2 /*return*/];
|
|
340
|
-
}
|
|
341
|
-
if (!confirm("Are you sure you want to remove the ".concat(propertyName, " property?"))) {
|
|
342
|
-
return [2 /*return*/];
|
|
343
|
-
}
|
|
344
|
-
_a.label = 1;
|
|
345
|
-
case 1:
|
|
346
|
-
_a.trys.push([1, 3, , 4]);
|
|
347
|
-
return [4 /*yield*/, hook.remove()];
|
|
348
|
-
case 2:
|
|
349
|
-
_a.sent();
|
|
350
|
-
setMessageText("".concat(propertyName, " property removed!"));
|
|
351
|
-
setShowMessage(true);
|
|
352
|
-
setTimeout(function () { return setShowMessage(false); }, 3000);
|
|
353
|
-
return [3 /*break*/, 4];
|
|
354
|
-
case 3:
|
|
355
|
-
error_5 = _a.sent();
|
|
356
|
-
setMessageText("Remove failed: ".concat(error_5 instanceof Error ? error_5.message : 'Unknown error'));
|
|
357
|
-
setShowMessage(true);
|
|
358
|
-
setTimeout(function () { return setShowMessage(false); }, 5000);
|
|
359
|
-
return [3 /*break*/, 4];
|
|
360
|
-
case 4: return [2 /*return*/];
|
|
220
|
+
else {
|
|
221
|
+
setKvStoreResult('(not found)');
|
|
361
222
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
223
|
+
setMessageText(item ? `Found key "${kvStoreKey}".` : `Key "${kvStoreKey}" not found.`);
|
|
224
|
+
setShowMessage(true);
|
|
225
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
setMessageText(`Get failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
229
|
+
setShowMessage(true);
|
|
230
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
231
|
+
}
|
|
232
|
+
}, [tenantKVStore, kvStoreKey]);
|
|
233
|
+
const handleKVStoreSave = React.useCallback(async () => {
|
|
234
|
+
if (!kvStoreKey || !kvStoreValue) {
|
|
235
|
+
setMessageText('Please enter both a key and a value.');
|
|
236
|
+
setShowMessage(true);
|
|
237
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
await tenantKVStore.save(kvStoreKey, kvStoreValue, kvStoreDescription || undefined);
|
|
242
|
+
setMessageText(`Saved key "${kvStoreKey}" successfully.`);
|
|
243
|
+
setShowMessage(true);
|
|
244
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
setMessageText(`Save failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
248
|
+
setShowMessage(true);
|
|
249
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
250
|
+
}
|
|
251
|
+
}, [tenantKVStore, kvStoreKey, kvStoreValue, kvStoreDescription]);
|
|
252
|
+
const handleKVStoreRemove = React.useCallback(async () => {
|
|
253
|
+
if (!kvStoreKey) {
|
|
254
|
+
setMessageText('Please enter a key to remove.');
|
|
255
|
+
setShowMessage(true);
|
|
256
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
await tenantKVStore.remove(kvStoreKey);
|
|
261
|
+
setKvStoreResult('');
|
|
262
|
+
setMessageText(`Removed key "${kvStoreKey}" successfully.`);
|
|
263
|
+
setShowMessage(true);
|
|
264
|
+
setTimeout(() => setShowMessage(false), 3000);
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
setMessageText(`Remove failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
268
|
+
setShowMessage(true);
|
|
269
|
+
setTimeout(() => setShowMessage(false), 5000);
|
|
270
|
+
}
|
|
271
|
+
}, [tenantKVStore, kvStoreKey]);
|
|
272
|
+
return (React.createElement("section", { className: `${styles.spFxReactToolkitTest} ${hasTeamsContext ? styles.teams : ''}` },
|
|
273
|
+
showMessage && (React.createElement(MessageBar, { messageBarType: MessageBarType.success, onDismiss: () => setShowMessage(false) }, messageText)),
|
|
366
274
|
React.createElement(Pivot, { "aria-label": "SPFx React Toolkit Demo Tabs", style: { marginTop: '20px' } },
|
|
367
275
|
React.createElement(PivotItem, { headerText: "Overview", itemIcon: "Home" },
|
|
368
276
|
React.createElement(Stack, { tokens: { childrenGap: 4 }, styles: { root: { marginTop: '16px' } } },
|
|
@@ -381,7 +289,7 @@ var SpFxReactToolkitTest = function () {
|
|
|
381
289
|
React.createElement(Icon, { iconName: "Settings", style: { marginRight: '8px' } }),
|
|
382
290
|
"Properties Editor",
|
|
383
291
|
React.createElement(Separator, null)),
|
|
384
|
-
React.createElement(TextField, { label: "Description Property", value: descriptionInput, onChange:
|
|
292
|
+
React.createElement(TextField, { label: "Description Property", value: descriptionInput, onChange: (_, newValue) => setDescriptionInput(newValue ?? ''), placeholder: "Enter description..." }),
|
|
385
293
|
React.createElement(PrimaryButton, { text: "Update Properties", onClick: handleUpdateProperties, iconProps: { iconName: 'Save' } }),
|
|
386
294
|
React.createElement(Label, null,
|
|
387
295
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
@@ -391,8 +299,8 @@ var SpFxReactToolkitTest = function () {
|
|
|
391
299
|
React.createElement(Icon, { iconName: "Resize", style: { marginRight: '8px' } }),
|
|
392
300
|
"Container Information",
|
|
393
301
|
React.createElement(Separator, null)),
|
|
394
|
-
React.createElement(InfoRow, { label: "Width", value:
|
|
395
|
-
React.createElement(InfoRow, { label: "Height", value:
|
|
302
|
+
React.createElement(InfoRow, { label: "Width", value: `${containerSize.width}px`, icon: "ArrowRight" }),
|
|
303
|
+
React.createElement(InfoRow, { label: "Height", value: `${containerSize.height}px`, icon: "ArrowUp" }),
|
|
396
304
|
React.createElement(InfoRow, { label: "DOM Element", value: containerInfo.element ? 'Available' : 'N/A', icon: "DOM" }),
|
|
397
305
|
React.createElement(InfoRow, { label: "Size Tracking", value: containerInfo.size ? 'Active' : 'Inactive', icon: "RadioBullet" }))))),
|
|
398
306
|
React.createElement(PivotItem, { headerText: "Context", itemIcon: "Contact" },
|
|
@@ -416,7 +324,7 @@ var SpFxReactToolkitTest = function () {
|
|
|
416
324
|
React.createElement(InfoRow, { label: "Text Direction", value: localeInfo.isRtl ? 'Right-to-Left (RTL)' : 'Left-to-Right (LTR)', icon: "TextAlignLeft" }),
|
|
417
325
|
localeInfo.timeZone && (React.createElement(React.Fragment, null,
|
|
418
326
|
React.createElement(InfoRow, { label: "Time Zone", value: localeInfo.timeZone.description, icon: "Clock" }),
|
|
419
|
-
React.createElement(InfoRow, { label: "UTC Offset", value:
|
|
327
|
+
React.createElement(InfoRow, { label: "UTC Offset", value: `${localeInfo.timeZone.offset} minutes`, icon: "DateTime" }),
|
|
420
328
|
React.createElement(Label, null,
|
|
421
329
|
React.createElement(Icon, { iconName: "Info", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
422
330
|
"Current time: ",
|
|
@@ -437,7 +345,7 @@ var SpFxReactToolkitTest = function () {
|
|
|
437
345
|
"Microsoft Teams Context",
|
|
438
346
|
React.createElement(Separator, null)),
|
|
439
347
|
React.createElement(InfoRow, { label: "Teams Supported", value: "Yes", icon: "CompletedSolid" }),
|
|
440
|
-
React.createElement(InfoRow, { label: "Teams Theme", value: teamsTheme
|
|
348
|
+
React.createElement(InfoRow, { label: "Teams Theme", value: teamsTheme ?? 'default', icon: "Color" }))),
|
|
441
349
|
listInfo && (React.createElement(Stack, { tokens: { childrenGap: 2 } },
|
|
442
350
|
React.createElement("h3", null,
|
|
443
351
|
React.createElement(Icon, { iconName: "BulletedList", style: { marginRight: '8px' } }),
|
|
@@ -449,7 +357,7 @@ var SpFxReactToolkitTest = function () {
|
|
|
449
357
|
listInfo.isDocumentLibrary && (React.createElement(Label, null,
|
|
450
358
|
React.createElement(Icon, { iconName: "FabricFolder", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
451
359
|
"Document Library")))),
|
|
452
|
-
|
|
360
|
+
hubInfo?.isHubSite && (React.createElement(Stack, { tokens: { childrenGap: 2 } },
|
|
453
361
|
React.createElement("h3", null,
|
|
454
362
|
React.createElement(Icon, { iconName: "NetworkTower", style: { marginRight: '8px' } }),
|
|
455
363
|
"Hub Site Association",
|
|
@@ -476,7 +384,7 @@ var SpFxReactToolkitTest = function () {
|
|
|
476
384
|
React.createElement(Label, null,
|
|
477
385
|
React.createElement(Icon, { iconName: "Info", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
478
386
|
"Check permissions on a different site (auto-fetch when URL is provided)"),
|
|
479
|
-
React.createElement(TextField, { label: "Target Site URL", value: crossSiteUrl || '', onChange:
|
|
387
|
+
React.createElement(TextField, { label: "Target Site URL", value: crossSiteUrl || '', onChange: (_, value) => setCrossSiteUrl(value?.trim() || undefined), placeholder: "https://contoso.sharepoint.com/sites/targetsite", description: "Enter a site URL - permissions will be fetched automatically" }),
|
|
480
388
|
crossSitePermissions.isLoading && (React.createElement(MessageBar, { messageBarType: MessageBarType.info },
|
|
481
389
|
"Loading permissions from ",
|
|
482
390
|
crossSiteUrl,
|
|
@@ -556,15 +464,13 @@ var SpFxReactToolkitTest = function () {
|
|
|
556
464
|
React.createElement(InfoRow, { label: "Is Not Found", value: oneDriveData.isNotFound ? 'Yes' : 'No', icon: "BlockedSiteSolid12" }))) : (React.createElement(Label, null, oneDriveData.isNotFound
|
|
557
465
|
? 'No file found yet. Click "Save to OneDrive" to create it.'
|
|
558
466
|
: 'No data loaded yet. Click "Load" to fetch from OneDrive.')),
|
|
559
|
-
React.createElement(TextField, { label: "New Message", value: oneDriveMessage, onChange:
|
|
467
|
+
React.createElement(TextField, { label: "New Message", value: oneDriveMessage, onChange: (_, newValue) => setOneDriveMessage(newValue ?? ''), placeholder: "Enter a message to save...", disabled: oneDriveData.isWriting || oneDriveData.isLoading }),
|
|
560
468
|
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
561
469
|
React.createElement(PrimaryButton, { text: "Load from OneDrive", onClick: handleLoadOneDrive, disabled: oneDriveData.isLoading || oneDriveData.isWriting, iconProps: { iconName: 'CloudDownload' } }),
|
|
562
470
|
React.createElement(PrimaryButton, { text: oneDriveData.isWriting ? 'Saving...' : 'Save to OneDrive', onClick: handleSaveOneDrive, disabled: !oneDriveMessage || oneDriveData.isWriting || oneDriveData.isLoading, iconProps: { iconName: 'CloudUpload' } })),
|
|
563
471
|
React.createElement(Label, null,
|
|
564
472
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
565
|
-
"Data is stored in your OneDrive (appRoot:/",
|
|
566
|
-
id,
|
|
567
|
-
"/test-data.json). Each WebPart instance has its own file."),
|
|
473
|
+
"Data is stored in your OneDrive (appRoot:/useSPFxOneDriveAppData/test-data.json)."),
|
|
568
474
|
React.createElement(Label, null,
|
|
569
475
|
React.createElement(Icon, { iconName: "Warning", style: { marginRight: '4px', color: '#d83b01' } }),
|
|
570
476
|
"Requires Microsoft Graph permissions: Files.ReadWrite or Files.ReadWrite.AppFolder")),
|
|
@@ -575,38 +481,69 @@ var SpFxReactToolkitTest = function () {
|
|
|
575
481
|
React.createElement(Separator, null)),
|
|
576
482
|
(tenantVersion.error || tenantCounter.error) && (React.createElement(MessageBar, { messageBarType: MessageBarType.error },
|
|
577
483
|
"Load Error: ",
|
|
578
|
-
|
|
579
|
-
(tenantVersion.writeError || tenantCounter.writeError) && (React.createElement(MessageBar, { messageBarType: MessageBarType.warning },
|
|
580
|
-
"Write Error: ",
|
|
581
|
-
((_e = tenantVersion.writeError) === null || _e === void 0 ? void 0 : _e.message) || ((_f = tenantCounter.writeError) === null || _f === void 0 ? void 0 : _f.message))),
|
|
484
|
+
tenantVersion.error?.message || tenantCounter.error?.message)),
|
|
582
485
|
(tenantVersion.isLoading || tenantCounter.isLoading) ? (React.createElement(MessageBar, { messageBarType: MessageBarType.info }, "Loading from tenant app catalog...")) : (tenantVersion.data || tenantCounter.data) ? (React.createElement(Stack, { tokens: { childrenGap: 1 } },
|
|
583
|
-
React.createElement(InfoRow, { label: "Version", value:
|
|
486
|
+
React.createElement(InfoRow, { label: "Version", value: tenantVersion.data ?? '(not set)', icon: "ServerEnviroment" }),
|
|
584
487
|
tenantVersion.description && (React.createElement(Label, null,
|
|
585
488
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
586
489
|
tenantVersion.description)),
|
|
587
|
-
React.createElement(InfoRow, { label: "Counter", value: String(
|
|
490
|
+
React.createElement(InfoRow, { label: "Counter", value: String(tenantCounter.data ?? 0), icon: "NumberField" }),
|
|
588
491
|
tenantCounter.description && (React.createElement(Label, null,
|
|
589
492
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
590
493
|
tenantCounter.description)),
|
|
591
|
-
React.createElement(InfoRow, { label: "
|
|
592
|
-
React.createElement(TextField, { label: "New Version", value: tenantVersionInput, onChange:
|
|
494
|
+
React.createElement(InfoRow, { label: "Mode", value: "Read-only (REST write blocked by Microsoft)", icon: "Permissions" }))) : (React.createElement(Label, null, "No data loaded yet. Click \"Load\" to fetch from tenant properties.")),
|
|
495
|
+
React.createElement(TextField, { label: "New Version", value: tenantVersionInput, onChange: (_, newValue) => setTenantVersionInput(newValue ?? ''), placeholder: "e.g., 1.0.0", disabled: tenantVersion.isLoading }),
|
|
593
496
|
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
594
497
|
React.createElement(PrimaryButton, { text: "Load Properties", onClick: handleLoadTenantProperty, disabled: tenantVersion.isLoading || tenantCounter.isLoading, iconProps: { iconName: 'CloudDownload' } }),
|
|
595
|
-
React.createElement(PrimaryButton, { text:
|
|
596
|
-
React.createElement(PrimaryButton, { text:
|
|
498
|
+
React.createElement(PrimaryButton, { text: "Save Version (disabled)", onClick: handleSaveTenantVersion, disabled: true, iconProps: { iconName: 'Save' } }),
|
|
499
|
+
React.createElement(PrimaryButton, { text: "Increment Counter (disabled)", onClick: handleIncrementTenantCounter, disabled: true, iconProps: { iconName: 'Add' } })),
|
|
597
500
|
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
598
|
-
React.createElement(DefaultButton, { text: "Remove Version", onClick:
|
|
599
|
-
React.createElement(DefaultButton, { text: "Remove Counter", onClick:
|
|
501
|
+
React.createElement(DefaultButton, { text: "Remove Version (disabled)", onClick: () => handleRemoveTenantProperty('version'), disabled: true, iconProps: { iconName: 'Delete' } }),
|
|
502
|
+
React.createElement(DefaultButton, { text: "Remove Counter (disabled)", onClick: () => handleRemoveTenantProperty('counter'), disabled: true, iconProps: { iconName: 'Delete' } })),
|
|
600
503
|
React.createElement(Label, null,
|
|
601
504
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
602
|
-
"Properties are
|
|
505
|
+
"Properties are read-only via REST API. Microsoft has blocked SetStorageEntity and RemoveStorageEntity endpoints."),
|
|
603
506
|
React.createElement(Label, null,
|
|
604
507
|
React.createElement(Icon, { iconName: "Info", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
605
508
|
"Keys: spfx-toolkit-test-version (string), spfx-toolkit-test-counter (number)"),
|
|
606
509
|
React.createElement(Label, null,
|
|
607
510
|
React.createElement(Icon, { iconName: "Warning", style: { marginRight: '4px', color: '#d83b01' } }),
|
|
608
|
-
"
|
|
609
|
-
|
|
511
|
+
"Use PowerShell (Set-PnPStorageEntity) to write tenant properties. For REST CRUD, use useSPFxTenantKeyValueStore."),
|
|
512
|
+
React.createElement(MessageBar, { messageBarType: MessageBarType.info }, "\u2139\uFE0F Write operations require PowerShell. Use useSPFxTenantKeyValueStore for REST-based CRUD.")),
|
|
513
|
+
React.createElement(Stack, { tokens: { childrenGap: 2 } },
|
|
514
|
+
React.createElement("h3", null,
|
|
515
|
+
React.createElement(Icon, { iconName: "TableGroup", style: { marginRight: '8px' } }),
|
|
516
|
+
"Tenant Key-Value Store Demo",
|
|
517
|
+
React.createElement(Separator, null)),
|
|
518
|
+
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 8 } },
|
|
519
|
+
React.createElement(StatusBadge, { label: "Ready", available: tenantKVStore.isReady }),
|
|
520
|
+
React.createElement(StatusBadge, { label: "Can Write", available: tenantKVStore.canWrite })),
|
|
521
|
+
tenantKVStore.error && (React.createElement(MessageBar, { messageBarType: MessageBarType.error },
|
|
522
|
+
"Read Error: ",
|
|
523
|
+
tenantKVStore.error.message)),
|
|
524
|
+
tenantKVStore.writeError && (React.createElement(MessageBar, { messageBarType: MessageBarType.error },
|
|
525
|
+
"Write Error: ",
|
|
526
|
+
tenantKVStore.writeError.message)),
|
|
527
|
+
React.createElement(TextField, { label: "Key", value: kvStoreKey, onChange: (_, v) => setKvStoreKey(v ?? ''), placeholder: "e.g., apiEndpoint" }),
|
|
528
|
+
React.createElement(TextField, { label: "Value", value: kvStoreValue, onChange: (_, v) => setKvStoreValue(v ?? ''), placeholder: "e.g., https://api.example.com" }),
|
|
529
|
+
React.createElement(TextField, { label: "Description (optional)", value: kvStoreDescription, onChange: (_, v) => setKvStoreDescription(v ?? ''), placeholder: "e.g., Production API endpoint" }),
|
|
530
|
+
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
531
|
+
React.createElement(PrimaryButton, { text: "List All", onClick: handleKVStoreList, disabled: tenantKVStore.isLoading || !tenantKVStore.isReady, iconProps: { iconName: 'BulletedList' } }),
|
|
532
|
+
React.createElement(PrimaryButton, { text: "Get", onClick: handleKVStoreGet, disabled: tenantKVStore.isLoading || !tenantKVStore.isReady, iconProps: { iconName: 'Search' } }),
|
|
533
|
+
React.createElement(PrimaryButton, { text: "Save", onClick: handleKVStoreSave, disabled: tenantKVStore.isWriting || !tenantKVStore.isReady, iconProps: { iconName: 'Save' } }),
|
|
534
|
+
React.createElement(DefaultButton, { text: "Remove", onClick: handleKVStoreRemove, disabled: tenantKVStore.isWriting || !tenantKVStore.isReady, iconProps: { iconName: 'Delete' } })),
|
|
535
|
+
kvStoreResult && (React.createElement(InfoRow, { label: "Get Result", value: kvStoreResult, icon: "StatusCircleCheckmark" })),
|
|
536
|
+
kvStoreItems.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 1 } },
|
|
537
|
+
React.createElement(Label, null,
|
|
538
|
+
React.createElement(Icon, { iconName: "BulletedList", style: { marginRight: '4px' } }),
|
|
539
|
+
"All Items (",
|
|
540
|
+
kvStoreItems.length,
|
|
541
|
+
")"),
|
|
542
|
+
kvStoreItems.map(item => (React.createElement(InfoRow, { key: item.id, label: item.key, value: typeof item.value === 'object' ? JSON.stringify(item.value) : String(item.value), icon: "Variable" }))))),
|
|
543
|
+
(tenantKVStore.isLoading || tenantKVStore.isWriting) && (React.createElement(MessageBar, { messageBarType: MessageBarType.info }, tenantKVStore.isWriting ? 'Writing...' : 'Loading...')),
|
|
544
|
+
React.createElement(Label, null,
|
|
545
|
+
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
546
|
+
"Uses hidden list \"TenantKeyValueStore\" in tenant app catalog. Requires Site Collection Admin for write.")),
|
|
610
547
|
React.createElement(Stack, { tokens: { childrenGap: 2 } },
|
|
611
548
|
React.createElement("h3", null,
|
|
612
549
|
React.createElement(Icon, { iconName: "Database", style: { marginRight: '8px' } }),
|
|
@@ -614,9 +551,9 @@ var SpFxReactToolkitTest = function () {
|
|
|
614
551
|
React.createElement(Separator, null)),
|
|
615
552
|
React.createElement(InfoRow, { label: "Current Value", value: sessionStorage.value || '(empty)', icon: "Variable" }),
|
|
616
553
|
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
617
|
-
React.createElement(TextField, { value: sessionStorageInput, onChange:
|
|
554
|
+
React.createElement(TextField, { value: sessionStorageInput, onChange: (_, newValue) => setSessionStorageInput(newValue ?? ''), placeholder: "Enter value...", styles: { root: { flexGrow: 1 } } }),
|
|
618
555
|
React.createElement(PrimaryButton, { text: "Save", onClick: handleSaveSessionStorage, iconProps: { iconName: 'Save' } }),
|
|
619
|
-
React.createElement(DefaultButton, { text: "Clear", onClick:
|
|
556
|
+
React.createElement(DefaultButton, { text: "Clear", onClick: () => sessionStorage.remove(), iconProps: { iconName: 'Delete' } })),
|
|
620
557
|
React.createElement(Label, null,
|
|
621
558
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
622
559
|
"Persists only for current tab/session")),
|
|
@@ -627,9 +564,9 @@ var SpFxReactToolkitTest = function () {
|
|
|
627
564
|
React.createElement(Separator, null)),
|
|
628
565
|
React.createElement(InfoRow, { label: "Current Value", value: localStorage.value || '(empty)', icon: "Variable" }),
|
|
629
566
|
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
630
|
-
React.createElement(TextField, { value: localStorageInput, onChange:
|
|
567
|
+
React.createElement(TextField, { value: localStorageInput, onChange: (_, newValue) => setLocalStorageInput(newValue ?? ''), placeholder: "Enter value...", styles: { root: { flexGrow: 1 } } }),
|
|
631
568
|
React.createElement(PrimaryButton, { text: "Save", onClick: handleSaveLocalStorage, iconProps: { iconName: 'Save' } }),
|
|
632
|
-
React.createElement(DefaultButton, { text: "Clear", onClick:
|
|
569
|
+
React.createElement(DefaultButton, { text: "Clear", onClick: () => localStorage.remove(), iconProps: { iconName: 'Delete' } })),
|
|
633
570
|
React.createElement(Label, null,
|
|
634
571
|
React.createElement(Icon, { iconName: "InfoSolid", style: { marginRight: '4px', color: '#0078d4' } }),
|
|
635
572
|
"Persists across sessions and page reloads")),
|
|
@@ -646,17 +583,17 @@ var SpFxReactToolkitTest = function () {
|
|
|
646
583
|
"Logger Demo",
|
|
647
584
|
React.createElement(Separator, null)),
|
|
648
585
|
React.createElement(Stack, { horizontal: true, tokens: { childrenGap: 2 } },
|
|
649
|
-
React.createElement(DefaultButton, { text: "Info", onClick:
|
|
650
|
-
React.createElement(DefaultButton, { text: "Warning", onClick:
|
|
651
|
-
React.createElement(DefaultButton, { text: "Error", onClick:
|
|
586
|
+
React.createElement(DefaultButton, { text: "Info", onClick: () => handleLog('info', 'This is an info message'), iconProps: { iconName: 'Info' } }),
|
|
587
|
+
React.createElement(DefaultButton, { text: "Warning", onClick: () => handleLog('warning', 'This is a warning message'), iconProps: { iconName: 'Warning' } }),
|
|
588
|
+
React.createElement(DefaultButton, { text: "Error", onClick: () => handleLog('error', 'This is an error message'), iconProps: { iconName: 'Error' } })),
|
|
652
589
|
logMessages.length > 0 && (React.createElement(Stack, { tokens: { childrenGap: 2 }, styles: { root: { marginTop: '8px' } } },
|
|
653
590
|
React.createElement(Label, null, "Recent Logs (check browser console):"),
|
|
654
|
-
logMessages.map(
|
|
655
|
-
|
|
591
|
+
logMessages.map((log, idx) => {
|
|
592
|
+
const levelClass = log.level === 'info' ? styles.info :
|
|
656
593
|
log.level === 'warning' ? styles.warning :
|
|
657
594
|
log.level === 'error' ? styles.error :
|
|
658
595
|
styles.verbose;
|
|
659
|
-
return (React.createElement("div", { key: idx, className:
|
|
596
|
+
return (React.createElement("div", { key: idx, className: `${styles.logMessage} ${levelClass}` },
|
|
660
597
|
React.createElement("strong", null,
|
|
661
598
|
"[",
|
|
662
599
|
log.level.toUpperCase(),
|
|
@@ -678,9 +615,9 @@ var SpFxReactToolkitTest = function () {
|
|
|
678
615
|
"Theme Information",
|
|
679
616
|
React.createElement(Separator, null)),
|
|
680
617
|
React.createElement(InfoRow, { label: "Is Dark Theme", value: isDarkTheme ? 'Yes' : 'No', icon: "Brightness" }),
|
|
681
|
-
React.createElement(InfoRow, { label: "Body Background", value:
|
|
682
|
-
React.createElement(InfoRow, { label: "Body Text", value:
|
|
683
|
-
React.createElement(InfoRow, { label: "Link Color", value:
|
|
618
|
+
React.createElement(InfoRow, { label: "Body Background", value: theme?.semanticColors?.bodyBackground ?? 'N/A', icon: "FabricFolderFill" }),
|
|
619
|
+
React.createElement(InfoRow, { label: "Body Text", value: theme?.semanticColors?.bodyText ?? 'N/A', icon: "Font" }),
|
|
620
|
+
React.createElement(InfoRow, { label: "Link Color", value: theme?.semanticColors?.link ?? 'N/A', icon: "Link" })),
|
|
684
621
|
React.createElement(Stack, { tokens: { childrenGap: 2 } },
|
|
685
622
|
React.createElement("h3", null,
|
|
686
623
|
React.createElement(Icon, { iconName: "Color", style: { marginRight: '8px' } }),
|