From b3c06cdaf4c057d2d7af122f97791b011a0c5b19 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Tue, 25 Aug 2026 17:31:41 -0400 Subject: [PATCH 01/12] Added flow. --- .../flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/apisMap.json | 1 + .../b0890fb0-8376-435a-bd78-094a5bc5fa4a/connectionsMap.json | 1 + .../flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/definition.json | 1 + flows/GetAdminsOwners/Microsoft.Flow/flows/manifest.json | 1 + flows/GetAdminsOwners/manifest.json | 1 + 5 files changed, 5 insertions(+) create mode 100644 flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/apisMap.json create mode 100644 flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/connectionsMap.json create mode 100644 flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/definition.json create mode 100644 flows/GetAdminsOwners/Microsoft.Flow/flows/manifest.json create mode 100644 flows/GetAdminsOwners/manifest.json diff --git a/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/apisMap.json b/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/apisMap.json new file mode 100644 index 0000000..10f2430 --- /dev/null +++ b/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/apisMap.json @@ -0,0 +1 @@ +{"shared_sharepointonline":"ff855bae-28f2-4a92-b639-8967beb6f93d"} \ No newline at end of file diff --git a/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/connectionsMap.json b/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/connectionsMap.json new file mode 100644 index 0000000..b0ff90a --- /dev/null +++ b/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/connectionsMap.json @@ -0,0 +1 @@ +{"shared_sharepointonline":"44c279dc-36b3-4935-b191-14e78df6fc2c"} \ No newline at end of file diff --git a/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/definition.json b/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/definition.json new file mode 100644 index 0000000..1e88a7b --- /dev/null +++ b/flows/GetAdminsOwners/Microsoft.Flow/flows/b0890fb0-8376-435a-bd78-094a5bc5fa4a/definition.json @@ -0,0 +1 @@ +{"name":"43128f15-3c9c-4169-9034-98832d0c77a7","id":"/providers/Microsoft.Flow/flows/43128f15-3c9c-4169-9034-98832d0c77a7","type":"Microsoft.Flow/flows","properties":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_logicflows","displayName":"Site Admin Lookup","definition":{"metadata":{"workflowEntityId":null,"processAdvisorMetadata":null,"flowChargedByPaygo":null,"flowclientsuspensionreason":"None","flowclientsuspensiontime":null,"flowclientsuspensionreasondetails":null,"creator":{"id":"4af50d87-e728-484e-874c-3f4536b38fee","type":"User","tenantId":"aecb54e0-7430-409d-86a4-7639c743eee7"},"provisioningMethod":"FromDefinition","failureAlertSubscription":true,"clientLastModifiedTime":"2026-08-25T20:18:46.4747484Z","lastModifiedBy":"4af50d87-e728-484e-874c-3f4536b38fee","connectionKeySavedTimeKey":"2026-08-25T20:18:46.4747484Z","creationSource":"Portal","modifiedSources":"Portal"},"$schema":"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#","contentVersion":"undefined","parameters":{"$authentication":{"defaultValue":{},"type":"SecureObject"},"$connections":{"defaultValue":{},"type":"Object"}},"triggers":{"manual":{"metadata":{},"type":"Request","kind":"Http","inputs":{"schema":{"url":""},"triggerAuthenticationType":"All"}}},"actions":{"Get_the_site_admins":{"runAfter":{"admins":["Succeeded"]},"type":"OpenApiConnection","inputs":{"parameters":{"dataset":"@variables('siteUrl')","parameters/method":"GET","parameters/uri":"_api/web/SiteUserInfoList/Items?$filter=IsSiteAdmin eq 1"},"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_sharepointonline","connectionName":"shared_sharepointonline","operationId":"HttpRequest"},"authentication":"@parameters('$authentication')"}},"Respond_to_a_Power_App_or_flow":{"runAfter":{"Loop_through_admins":["Succeeded"],"Loop_through_owners":["Succeeded"]},"type":"Response","kind":"PowerApp","inputs":{"schema":{"type":"object","properties":{"admins":{"title":"admins","type":"string","x-ms-content-hint":"TEXT","x-ms-dynamically-added":true},"owners":{"title":"owners","type":"string","x-ms-content-hint":"TEXT","x-ms-dynamically-added":true}},"additionalProperties":{}},"statusCode":200,"body":{"admins":"@{variables('admins')}","owners":"@{variables('owners')}"}}},"admins":{"runAfter":{"siteUrl":["Succeeded"]},"type":"InitializeVariable","inputs":{"variables":[{"name":"admins","type":"array"}]}},"Loop_through_admins":{"foreach":"@body('Get_the_site_admins')?['d']?['results']","actions":{"Add_the_site_admin":{"type":"AppendToArrayVariable","inputs":{"name":"admins","value":{"name":"@items('Loop_through_admins')?['Title']","email":"@items('Loop_through_admins')?['EMail']","type":"@items('Loop_through_admins')?['SPSUserType']"}}}},"runAfter":{"Get_the_site_admins":["Succeeded"]},"type":"Foreach"},"owners":{"runAfter":{"siteUrl":["Succeeded"]},"type":"InitializeVariable","inputs":{"variables":[{"name":"owners","type":"array"}]}},"Get_the_site_owners_group":{"runAfter":{"owners":["Succeeded"]},"type":"OpenApiConnection","inputs":{"parameters":{"dataset":"@variables('siteUrl')","parameters/method":"GET","parameters/uri":"_api/web/AssociatedOwnerGroup/Users"},"host":{"apiId":"/providers/Microsoft.PowerApps/apis/shared_sharepointonline","connectionName":"shared_sharepointonline","operationId":"HttpRequest"},"authentication":"@parameters('$authentication')"}},"Loop_through_owners":{"foreach":"@body('Get_the_site_owners_group')['d']['results']","actions":{"Add_the_owner":{"type":"AppendToArrayVariable","inputs":{"name":"owners","value":{"name":"@items('Loop_through_owners')?['Title']","email":"@items('Loop_through_owners')?['Email']","type":"@items('Loop_through_owners')?['PrincipalType']"}}}},"runAfter":{"Get_the_site_owners_group":["Succeeded"]},"type":"Foreach"},"siteUrl":{"runAfter":{},"type":"InitializeVariable","inputs":{"variables":[{"name":"siteUrl","type":"string","value":"@triggerBody()['url']"}]}}}},"connectionReferences":{"shared_sharepointonline":{"connectionName":"shared-sharepointonl-66a6d844-5e1b-4fa5-a8f1-40d37f28a005","source":"Embedded","id":"/providers/Microsoft.PowerApps/apis/shared_sharepointonline","tier":"NotSpecified","apiName":"sharepointonline","isProcessSimpleApiReferenceConversionAlreadyDone":false}},"flowFailureAlertSubscribed":false,"isManaged":false}} \ No newline at end of file diff --git a/flows/GetAdminsOwners/Microsoft.Flow/flows/manifest.json b/flows/GetAdminsOwners/Microsoft.Flow/flows/manifest.json new file mode 100644 index 0000000..de24c6b --- /dev/null +++ b/flows/GetAdminsOwners/Microsoft.Flow/flows/manifest.json @@ -0,0 +1 @@ +{"packageSchemaVersion":"1.0","flowAssets":{"assetPaths":["b0890fb0-8376-435a-bd78-094a5bc5fa4a"]}} \ No newline at end of file diff --git a/flows/GetAdminsOwners/manifest.json b/flows/GetAdminsOwners/manifest.json new file mode 100644 index 0000000..b7ff233 --- /dev/null +++ b/flows/GetAdminsOwners/manifest.json @@ -0,0 +1 @@ +{"schema":"1.0","details":{"displayName":"Site Admin Tool - Get Admins/Owners","description":"Flow to return the site admins and owners of a site.","createdTime":"2026-08-25T21:14:03.9176328Z","packageTelemetryId":"744faeef-8171-4ff9-91bf-a4fb3a96c35b","creator":"N/A","sourceEnvironment":"Commercial"},"resources":{"b0890fb0-8376-435a-bd78-094a5bc5fa4a":{"type":"Microsoft.Flow/flows","suggestedCreationType":"New","creationType":"Existing, New, Update","details":{"displayName":"Site Admin Lookup"},"configurableBy":"User","hierarchy":"Root","dependsOn":["ff855bae-28f2-4a92-b639-8967beb6f93d","44c279dc-36b3-4935-b191-14e78df6fc2c"]},"ff855bae-28f2-4a92-b639-8967beb6f93d":{"id":"/providers/Microsoft.PowerApps/apis/shared_sharepointonline","name":"shared_sharepointonline","type":"Microsoft.PowerApps/apis","suggestedCreationType":"Existing","details":{"displayName":"SharePoint","iconUri":"https://static.powerapps.com/resource/ppcr/releases/v1.0.1813/1.0.1813.4769/sharepointonline/icon.png"},"configurableBy":"System","hierarchy":"Child","dependsOn":[]},"44c279dc-36b3-4935-b191-14e78df6fc2c":{"type":"Microsoft.PowerApps/apis/connections","suggestedCreationType":"Existing","creationType":"Existing","details":{"displayName":"gunjan@dattaspo.onmicrosoft.com","iconUri":"https://static.powerapps.com/resource/ppcr/releases/v1.0.1813/1.0.1813.4769/sharepointonline/icon.png"},"configurableBy":"User","hierarchy":"Child","dependsOn":["ff855bae-28f2-4a92-b639-8967beb6f93d"]}}} \ No newline at end of file From fb6f9dbdda6b3791eb7d0c91027f077f3b0d0271 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Tue, 25 Aug 2026 17:31:51 -0400 Subject: [PATCH 02/12] Updated SPFx properties. --- spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts b/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts index be15a8a..9f32baf 100644 --- a/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts +++ b/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts @@ -71,12 +71,12 @@ export interface ISiteAdminWebPartProps { AppTitle: string; AuditOnly: boolean; DisableSensitivityLabelOverride: boolean; + FlowGetSiteAdminsAndOwners: string; HideAppPermissionsTab: boolean; HideAuditToolsTab: boolean; HideFeaturesTab: boolean; HideListsTab: boolean; HideCreateSiteBtn: boolean; - HideLoadAdminOwnerBtn: boolean; HideLoadOneDriveBtn: boolean; HideManagementTab: boolean; HideSearchTab: boolean; @@ -212,8 +212,8 @@ declare const SiteAdmin: { el: HTMLElement; title?: string; disableSensitivityLabelOverride?: boolean; + flowGetSiteAdminsAndOwners?: string; hideCreateSiteBtn?: boolean; - hideLoadAdminOwnerBtn: boolean; hideLoadOneDriveBtn: boolean; hideReports: { dlp: boolean; @@ -481,11 +481,10 @@ export default class SiteAdminWebPart extends BaseClientSideWebPart Date: Tue, 25 Aug 2026 17:32:03 -0400 Subject: [PATCH 03/12] Updated logic to call flow instead of REST API. --- src/app.ts | 6 +++--- src/ds.ts | 56 ++++++++++++------------------------------------- src/loadForm.ts | 22 +++++++++---------- 3 files changed, 27 insertions(+), 57 deletions(-) diff --git a/src/app.ts b/src/app.ts index 0e3f161..6dd2303 100644 --- a/src/app.ts +++ b/src/app.ts @@ -22,8 +22,8 @@ export interface IAppProps { context?: any; disableSensitivityLabelOverride?: boolean; el: HTMLElement; + flowGetSiteAdminsAndOwners?: string; hideCreateSiteBtn?: boolean; - hideLoadAdminOwnerBtn?: boolean; hideLoadOneDriveBtn?: boolean; hideReports: { dlp?: boolean; @@ -119,7 +119,7 @@ export class App { // Render the form new LoadForm(el.children[0].children[0] as HTMLElement, el.children[0].children[1] as HTMLElement, - this._props.hideLoadAdminOwnerBtn, this._props.hideLoadOneDriveBtn, () => { + this._props.flowGetSiteAdminsAndOwners, this._props.hideLoadOneDriveBtn, () => { // Render the tabs new App(this._props, false); }, () => { @@ -154,7 +154,7 @@ export class App { text: "Load Site", onClick: () => { // Show the load form - LoadForm.showModal(this._props.hideLoadAdminOwnerBtn, this._props.hideLoadOneDriveBtn, () => { + LoadForm.showModal(this._props.flowGetSiteAdminsAndOwners, this._props.hideLoadOneDriveBtn, () => { // Render the tabs this.renderTabs(elRow.children[1] as HTMLElement, false); }, () => { diff --git a/src/ds.ts b/src/ds.ts index 9763d99..d7330f7 100644 --- a/src/ds.ts +++ b/src/ds.ts @@ -433,51 +433,21 @@ export class DataSource { } // Loads the admins/owners of the site - static loadAdminsOwners(siteUrl: string): PromiseLike<{ admins: IUserInfo[], owners: IUserInfo[] }> { + static loadAdminsOwners(flowUri: string, siteUrl: string): PromiseLike<{ admins: IUserInfo[], owners: IUserInfo[] }> { // Return a promise return new Promise((resolve, reject) => { - let errorFl = false; - let web = Web(siteUrl); - - // Get the admins - let admins: IUserInfo[] = []; - web.SiteUserInfoList().Items().query({ - Filter: "IsSiteAdmin eq 1" - }).execute(users => { - // Add the admins - users.results.forEach(user => { - admins.push({ - email: user["EMail"] || user["UserName"], - name: user.Title, - type: "Site Admin" - }); - }); - }, () => { - // Set the flag - errorFl = true; - }); - - // Get the owners - let owners: IUserInfo[] = []; - web.AssociatedOwnerGroup().Users().execute(users => { - // Add the owners - users.results.forEach(user => { - owners.push({ - email: user.Email || user.LoginName, - name: user.Title, - type: "Site Owner" - }); - }); - }, () => { - // Set the flag - errorFl = true; - }, true); - - // Wait for the requests to complete - web.done(() => { - // Complete the request - errorFl ? reject() : resolve({ admins, owners }) - }); + // Call the flow + fetch(flowUri, { + method: "POST", + headers: { + "Accept": "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify({ url: siteUrl }) + }) + .then(resp => { return resp.json(); }) + .then(resp => { resolve(resp); }) + .catch(ex => { reject(ex); }); }); } diff --git a/src/loadForm.ts b/src/loadForm.ts index f14f45e..a66f722 100644 --- a/src/loadForm.ts +++ b/src/loadForm.ts @@ -14,30 +14,30 @@ export class LoadForm { private _onLoadOneDrive: () => void = null; // Renders the modal - constructor(elForm: HTMLElement, elFooter: HTMLElement, hideLoadAdminOwnerBtn: boolean = false, hideLoadOneDriveBtn: boolean = false, onSuccess: () => void, onLoadOneDrive: () => void) { + constructor(elForm: HTMLElement, elFooter: HTMLElement, flowGetSiteAdminsAndOwners: string, hideLoadOneDriveBtn: boolean = false, onSuccess: () => void, onLoadOneDrive: () => void) { this._onSuccess = onSuccess; this._onLoadOneDrive = onLoadOneDrive; // Render the form and footer this.renderForm(elForm); - this.renderFooter(elFooter, hideLoadAdminOwnerBtn, hideLoadOneDriveBtn); + this.renderFooter(elFooter, flowGetSiteAdminsAndOwners, hideLoadOneDriveBtn); } // Renders the footer - private renderFooter(el: HTMLElement, hideLoadAdminOwnerBtn: boolean, hideLoadOneDriveBtn: boolean) { + private renderFooter(el: HTMLElement, flowGetSiteAdminsAndOwners: string, hideLoadOneDriveBtn: boolean) { // Clear the element while (el.firstChild) { el.removeChild(el.firstChild); } // Set the tooltips let tooltips = [] - if (!hideLoadAdminOwnerBtn) { + if (flowGetSiteAdminsAndOwners) { tooltips.push({ content: "Views the owners/admins of the site.", btnProps: { text: "View Admins/Owners", onClick: () => { // Load the admins/owners of the site - this.viewAdminsOwners(); + this.viewAdminsOwners(flowGetSiteAdminsAndOwners); } } }); @@ -265,7 +265,7 @@ export class LoadForm { } // Shows the modal - static showModal(hideLoadAdminOwnerBtn: boolean = false, hideLoadOneDriveBtn: boolean = false, onSuccess: () => void, onLoadOneDrive: () => void) { + static showModal(flowGetSiteAdminsAndOwners: string, hideLoadOneDriveBtn: boolean = false, onSuccess: () => void, onLoadOneDrive: () => void) { // Clear the modal Modal.clear(); @@ -273,7 +273,7 @@ export class LoadForm { Modal.setHeader("Load Site"); // Create the form/footer - new LoadForm(Modal.BodyElement, Modal.FooterElement, hideLoadAdminOwnerBtn, hideLoadOneDriveBtn, onSuccess, onLoadOneDrive); + new LoadForm(Modal.BodyElement, Modal.FooterElement, flowGetSiteAdminsAndOwners, hideLoadOneDriveBtn, onSuccess, onLoadOneDrive); // Show the modal Modal.show(); @@ -322,19 +322,19 @@ export class LoadForm { } // Views the admins/owners of the site - private viewAdminsOwners() { + private viewAdminsOwners(flowGetSiteAdminsAndOwners: string) { // Validate the form if (this._form.isValid()) { let ctrl = this._form.getControl("url"); let url = this._form.getValues()["url"]; // Show a loading dialog - LoadingDialog.setHeader("Validating Site"); - LoadingDialog.setBody("This will close after the site url is validated..."); + LoadingDialog.setHeader("Calling Flow"); + LoadingDialog.setBody("This will close after the flow has completed..."); LoadingDialog.show(); // Load the admins/owners - DataSource.loadAdminsOwners(typeof (url) === "string" ? url : url.value).then( + DataSource.loadAdminsOwners(flowGetSiteAdminsAndOwners, typeof (url) === "string" ? url : url.value).then( // Success users => { // Clear the modal From 2567f6c9772e071f3ba5265bcf94d5bd87f65f96 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Tue, 25 Aug 2026 19:41:23 -0400 Subject: [PATCH 04/12] Moved the flow settings to its own group. --- spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts b/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts index 9f32baf..5490601 100644 --- a/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts +++ b/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts @@ -481,11 +481,6 @@ export default class SiteAdminWebPart extends BaseClientSideWebPart Date: Tue, 25 Aug 2026 19:44:25 -0400 Subject: [PATCH 05/12] add debug for testing. --- spfx/config/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spfx/config/config.json b/spfx/config/config.json index a7d7af3..8934d92 100644 --- a/spfx/config/config.json +++ b/spfx/config/config.json @@ -14,7 +14,7 @@ "externals": { "main-lib": { "globalName": "main-lib", - "path": "../dist/site-admin.min.js" + "path": "../dist/site-admin.js" } }, "localizedResources": { From ba6007fa93f50b632a33f70dbc4f675550f01c3e Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Tue, 25 Aug 2026 19:55:51 -0400 Subject: [PATCH 06/12] Fixed spfx property. --- spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts b/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts index 5490601..05b5c90 100644 --- a/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts +++ b/spfx/src/webparts/siteAdmin/SiteAdminWebPart.ts @@ -536,7 +536,7 @@ export default class SiteAdminWebPart extends BaseClientSideWebPart Date: Tue, 25 Aug 2026 21:02:00 -0400 Subject: [PATCH 07/12] Fixed the url to be absolute. --- src/loadForm.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/loadForm.ts b/src/loadForm.ts index a66f722..3dbf255 100644 --- a/src/loadForm.ts +++ b/src/loadForm.ts @@ -333,8 +333,11 @@ export class LoadForm { LoadingDialog.setBody("This will close after the flow has completed..."); LoadingDialog.show(); + // Set the absolute url of the site + let siteUrl = document.location.origin + typeof (url) === "string" ? url : url.value; + // Load the admins/owners - DataSource.loadAdminsOwners(flowGetSiteAdminsAndOwners, typeof (url) === "string" ? url : url.value).then( + DataSource.loadAdminsOwners(flowGetSiteAdminsAndOwners, siteUrl).then( // Success users => { // Clear the modal From fbcb78f6f9d3e476d9d20474683f59d2e1dc87b7 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Tue, 25 Aug 2026 21:06:26 -0400 Subject: [PATCH 08/12] Updated the response to check for success. --- src/ds.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ds.ts b/src/ds.ts index d7330f7..1151b62 100644 --- a/src/ds.ts +++ b/src/ds.ts @@ -445,7 +445,14 @@ export class DataSource { }, body: JSON.stringify({ url: siteUrl }) }) - .then(resp => { return resp.json(); }) + .then(resp => { + // Ensure it was successful + if(resp.ok) { + return resp.json(); + } else { + throw new Error("Failed to load admins/owners"); + } + }) .then(resp => { resolve(resp); }) .catch(ex => { reject(ex); }); }); From 59c2a09015f57a3e4e997713fe32ac281fb39434 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Tue, 25 Aug 2026 21:13:30 -0400 Subject: [PATCH 09/12] Fixed issue w/ setting the site url. --- src/loadForm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loadForm.ts b/src/loadForm.ts index 3dbf255..21caf0e 100644 --- a/src/loadForm.ts +++ b/src/loadForm.ts @@ -334,7 +334,7 @@ export class LoadForm { LoadingDialog.show(); // Set the absolute url of the site - let siteUrl = document.location.origin + typeof (url) === "string" ? url : url.value; + let siteUrl = document.location.origin + (typeof (url) === "string" ? url : url.value); // Load the admins/owners DataSource.loadAdminsOwners(flowGetSiteAdminsAndOwners, siteUrl).then( From f2082577b332114ee9e210458d49082bb4a98564 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Wed, 26 Aug 2026 08:15:44 -0400 Subject: [PATCH 10/12] Fixed the data returned to ensure it's an object not string. --- src/ds.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/ds.ts b/src/ds.ts index 1151b62..c3508e1 100644 --- a/src/ds.ts +++ b/src/ds.ts @@ -447,13 +447,22 @@ export class DataSource { }) .then(resp => { // Ensure it was successful - if(resp.ok) { + if (resp.ok) { return resp.json(); } else { throw new Error("Failed to load admins/owners"); } }) - .then(resp => { resolve(resp); }) + .then(resp => { + // Ensure the data is converted + if (typeof (resp.admins) === "string") { + resp.admins = JSON.parse(resp.admins); + } + if (typeof (resp.owners) === "string") { + resp.owners = JSON.parse(resp.owners); + } + resolve(resp); + }) .catch(ex => { reject(ex); }); }); } From cd3497de6865f3df05a21e6371ed17081b47ab86 Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Wed, 26 Aug 2026 08:29:30 -0400 Subject: [PATCH 11/12] Updated the table to sort by user type. --- spfx/config/config.json | 2 +- src/loadForm.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/spfx/config/config.json b/spfx/config/config.json index 8934d92..a7d7af3 100644 --- a/spfx/config/config.json +++ b/spfx/config/config.json @@ -14,7 +14,7 @@ "externals": { "main-lib": { "globalName": "main-lib", - "path": "../dist/site-admin.js" + "path": "../dist/site-admin.min.js" } }, "localizedResources": { diff --git a/src/loadForm.ts b/src/loadForm.ts index 21caf0e..cc5dec8 100644 --- a/src/loadForm.ts +++ b/src/loadForm.ts @@ -350,6 +350,13 @@ export class LoadForm { new DataTable({ el: Modal.BodyElement, rows: users.admins.concat(users.owners), + onRendering: dtProps => { + // Order by the 1st column + dtProps.order = [[0, "asc"]]; + + // Return the properties + return dtProps; + }, columns: [ { name: "type", From c3c6593d06b62812157feae45a86cb5b244f47dd Mon Sep 17 00:00:00 2001 From: Gunjan Datta Date: Wed, 26 Aug 2026 09:27:00 -0400 Subject: [PATCH 12/12] Updated lib to fix a styling issue. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 81b236e..c9b86db 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "adm-zip": "^0.5.18", "datatables.net": "^3.0.0", "datatables.net-bs5": "^3.0.0", - "dattatable": "^2.11.87", + "dattatable": "^2.11.88", "exceljs": "^4.4.0", "fast-xml-parser": "^5.9.3", "gd-sprest-bs": "^10.15.92",