...
version | 4 |
---|
...
Edit Confluence page, add HTML Macro for Confluence or Advanced Macro for Confluence to your page
...
The macro editor will be opened. Copy & paste below code to the macro and adjust it based on your requirement.
Code Block | ||
---|---|---|
| ||
<div id=\"group-audit-container\" class=\"aui\">\n> <label<form forclass=\"groupName\"aui" style="margin-top: 20px; margin-left: 10px; margin-right: 10px;" onsubmit="return false;" > <label for="groupName">Select Group: </label>\n <select id=\"groupName\" class=\"select\">\n <option value=\"1\">administrators</option>\n <option value=\"2\">site-admins</option>\n <option value=\"3\">confluence-users</option>\n </select>\n <button id=\"fetchGroupDetails\" class=\"aui-button\">Fetch Group Details</button>\n <div id=\"groupDetails\" style=\"margin-top: 20px; border: 1px solid #ddd; padding: 10px;\"></div>\n</div>\n\n<script>\n \n fetchGroups();\n async function fetchGroups(){ </form> </div> <script> fetchGroups(); async function fetchGroups(){ let groups = []; let url = `/rest/api/group`; while(url){ try{ const response = await AP.request({ url: url, type: "GET", contentType: "application/json" }); let data = JSON.parse(response.body); if (!data.results || data.results.length === 0) { break; } groups = groups.concat(data.results); url = data._links.next; } catch (error) { console.error("Error:", error); url = undefined; } } if(groups.length === 0){ return; } const groupSelect = document.getElementById("groupName"); groupSelect.innerHTML = ""; // Clear existing options groups.forEach(group => { const option = document.createElement("option"); option.value = group.id; option.textContent = group.name; groupSelect.appendChild(option); }); } async function fetchGroupMembers(groupId) { const groupDetailsDiv = document.getElementById("groupDetails"); groupDetailsDiv.textContent = "Fetching group details..."; let groupMembers = []; let url = `/rest/api/group/${groupId}/membersByGroupId`; while(url){ try { const response = await AP.request({ url: url, type: "GET", contentType: "application/json" }); if (response.xhr.status !== 200) { throw new Error(`Error fetching group members: ${response.statusText}`); } let data = JSON.parse(response.body); if (!data.results || data.results.length === 0) { break; } groupMembers = groupMembers.concat(data.results); url = data._links.next; } catch (error) { console.error("Error:", error); groupDetailsDiv.textContent = "Failed to fetch group members. Check the console for details."; url = undefined; } } if (groupMembers.length === 0) { groupDetailsDiv.textContent = "No members found for this group."; return; } // Build and display the table let table = ` <table class="aui" border="1" style="width: 100%; border-collapse: collapse;"> <thead> <tr> <th></th> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> `; for (const member of groupMembers) { let img = `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`; img = member.profilePicture?.path; if (!img) { img = `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`; } else{ if(!img.startsWith("http")){ img = `${AP._hostOrigin}/${img}`; } } table += ` <tr> <td><img style="width:32px; hight:32px;" src="${img}" alt="Avatar"></td> <td>${member.displayName}</td> <td>${member.emailAddress || "N/A"}</td> </tr> `; } table += "</tbody></table>"; groupDetailsDiv.innerHTML = table; } document.getElementById("fetchGroupDetails").addEventListener("click", () => { const groupId = document.getElementById("groupName").value.trim(); if (!groupId) { alert("Please select a group."); return; } fetchGroupMembers(groupId); }); </script> |
Publish your page and see the result:
Advanced html | ||
---|---|---|
| ||
{"htmlContent":"\n<div id=\"group-audit-container\">\n <form class=\"aui\" style=\"margin-top: 20px; margin-left: 10px; margin-right: 10px;\" onsubmit=\"return false;\" >\n <label for=\"groupName\">Select Group: </label>\n <select id=\"groupName\" class=\"select\">\n <option value=\"1\">administrators</option>\n <option value=\"2\">site-admins</option>\n <option value=\"3\">confluence-users</option>\n </select>\n <button id=\"fetchGroupDetails\" class=\"aui-button\">Fetch Group Details</button>\n <div id=\"groupDetails\" style=\"margin-top: 20px; border: 1px solid #ddd; padding: 10px;\"></div>\n </form>\n</div>\n\n<script>\n \n fetchGroups();\n async function fetchGroups(){\n\n let groups = [];\n let url = `/rest/api/group`;\n while(url){\n\n try{\n const response = await AP.request({\n url: url, \n type: \"GET\",\n contentType: \"application/json\"\n });\n\n let data = JSON.parse(response.body);\n\n if (!data.results || data.results.length === 0) {\n break;\n }\n\n groups = groups.concat(data.results);\n url = data._links.next; \n\n } catch (error) {\n console.error(\"Error:\", error);\n url = undefined;\n } \n }\n\n //console.log(groups);\n\n if(groups.length === 0){\n\n fetchGroupMembers(1); // Hardcoded group members for testing\n //alert(\"No groups found\");\n return;\n }\n\n const groupSelect = document.getElementById(\"groupName\");\n groupSelect.innerHTML = \"\"; // Clear existing options\n\n groups.forEach(group => {\n const option = document.createElement(\"option\");\n option.value = group.id;\n option.textContent = group.name;\n groupSelect.appendChild(option);\n });\n }\n \n\n async function fetchGroupMembers(groupId) {\n const groupDetailsDiv = document.getElementById(\"groupDetails\");\n groupDetailsDiv.textContent = \"Fetching group details...\";\n\n let groupMembers = [];\n let url = `/rest/api/group/${groupId}/membersByGroupId`;\n\n while(url){\n\n try {\n const response = await AP.request({\n url: url, \n type: \"GET\",\n contentType: \"application/json\"\n });\n\n if (response.xhr.status !== 200) {\n throw new Error(`Error fetching group members: ${response.statusText}`);\n }\n\n let groups = [];\n let urldata = `/rest/api/group`JSON.parse(response.body);\n\n while(url){\n\n if (!data.results || data.results.length === 0) try{\n const\n response = await AP.request({\n break;\n url: url, }\n\n groupMembers = groupMembers.concat(data.results);\n type: \"GET\",\n url = data._links.next; contentType: \"application/json\" \n\n } catch });(error) {\n\n let data = JSON.parse(response.bodyconsole.error(\"Error:\", error);\n\n groupDetailsDiv.textContent if (!data.results || data.results.length === 0) {= \"Failed to fetch group members. Check the console for details.\";\n url = breakundefined;\n }\n\n }\n\n if groups(groupMembers.length = groups.concat(data.results);== 0) {\n url = data._links.next; \n//groupDetailsDiv.textContent = \"No members found for this group.\";\n } catch (error) {//return;\n if(groupId == 1){ console.error(\"Error:\", error);\n // Hardcoded group members for testing url = undefined;\n } groupMembers = [\n }\n\n //console.log(groups);\n{\n if(groups.length === 0){\n //alert(\"displayName\"No: groups\"John foundDoe\");,\n return;\n }\n\n const groupSelect = document.getElementById(\"groupName\");\"emailAddress\": \"john@example.com\",\n groupSelect.innerHTML = \"\"; // Clear existing options\n\n groups.forEach(group => \"profilePicture\": {\n const option = document.createElement(\"option\");\n option.value = group.id;\n option.textContent = group.name; \"path\": \"https://icon-library.com/images/admin-user-icon/admin-user-icon-4.jpg\"\n groupSelect.appendChild(option);\n });\n }\n \n\n async function fetchGroupMembers(groupId) {\n const groupDetailsDiv = document.getElementById(\"groupDetails\");\n },\n groupDetailsDiv.textContent = \"Fetching group details...\";\n\n let groupMembers = [];{\n let url = `/rest/api/group/${groupId}/membersByGroupId`;\n\n while(url){\n\n \"displayName\": \"Jane Smith\",\n try {\n const response = await AP.request({ \"emailAddress\": \"jane@example.com\",\n url: url, \"profilePicture\": {\n \n type\"path\": \"GEThttps://icon-library.com/images/google-user-icon/google-user-icon-11.jpg\",\nn contentType: \"application/json\" }\n });,\n\n if (response.xhr.status !== 200) {\n throw new Error(`Error fetching group members: ${response.statusText}`);\n }\n \"displayName\": \"Alice Brown\",\n let data = JSON.parse(response.body);\n\n \"emailAddress\": \"alice@example.com\",\n if (!data.results || data.results.length === 0) { \"profilePicture\": {\n break;\n }\n\n\"path\": \"https://icon-library.com/images/user-icon-png/user-icon-png-29.jpg\"\n groupMembers = groupMembers.concat(data.results);\n }\n }\n url = data._links.next; \n];\n } catch (error) {\n else if(groupId console.error(\"Error:\", error);== 2){\n groupDetailsDiv.textContentgroupMembers = [\"Failedn to fetch group members. Check the console for details.\";\n {\n url = undefined;\n }\n \"displayName\": \"Bob }Johnson\n",\n if (groupMembers.length === 0) {\n //groupDetailsDiv.textContent = \"No members found for this group.\";\"emailAddress\": \"bob@example.com\",\n //return;\n if(groupId == 1){\"profilePicture\": {\n \n groupMembers = [ \"path\": \"https://icon-library.com/images/user-png-icon/user-png-icon-5.jpg\"\n {\n }\n \"displayName\": \"John Doe\"},\n {\n \"emailAddress\": \"john@example.com\"\n \"displayName\": }\"Charlie White\",\n { \"emailAddress\": \"charlie@example.com\",\n \"displayNameprofilePicture\": \"Jane Smith\",\n{\n \"emailAddresspath\": \"janeĢ@example.com\"https://icon-library.com/images/user-image-icon/user-image-icon-10.jpg\"\n },\n {}\n \"displayName\": \"Alice Brown\",\];\n }\n \"emailAddress\": \"alice@example.com\"else{\n groupMembers = }[\n ];\n }{\n else if(groupId == 2){\n \"displayName\": \"David Black\",\n groupMembers = [\n {\"emailAddress\": \"david@example.com\",\n \"displayNameprofilePicture\": \"Bob Johnson\",\n{\n \"emailAddresspath\": \"bob@example.comhttps://icon-library.com/images/icon-for-user/icon-for-user-1.jpg\"\n },\n {}\n \"displayName\": \"Charlie White\",\];\n \"emailAddress\": \"charlie@example.com\"}\n }\n\n // Build and display the }table\n let table ];= `\n }\n <table class=\"aui\" border=\"1\" style=\"width: 100%; else{border-collapse: collapse;\">\n groupMembers = [<thead>\n <tr>\n {\n <th></th> \"displayName\": \"David Black\",\n \n \"emailAddress\": \"david@example.com\"\ <th>Name</th>\n }<th>Email</th>\n ];</tr>\n }\n </thead>\n }\n\n // Build and display the table<tbody>\n let table = `\n `;\n\n <table class=\"aui\" border=\"1\" style=\"width: 100%; border-collapse: collapse;\"> for (const member of groupMembers) {\n\n let img <thead>= `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n img <tr>= member.profilePicture?.path;\n if (!img) {\n <th>Name</th>\n img <th>Email</th>= `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n }\n <th>Product Access</th>\n else{\n </tr>\n if(!img.startsWith(\"http\")){\n </thead>\n img <tbody>= `${AP._hostOrigin}/${img}`;\n `;\n}\n for (const member of groupMembers) {}\n table += `\n // Display member info (dummy product access added for simplicity)\n table += `<tr>\n <tr><td><img style=\"width:32px; hight:32px;\" src=\"${img}\" alt=\"Avatar\"></td>\n <td>${member.displayName}</td>\n <td>${member.emailAddress || \"N/A\"}</td>\n <td>No Product Access API in Confluence Cloud</td>\n </tr>\n `;\n }\n\n table += \"</tbody></table>\";\n groupDetailsDiv.innerHTML = table;\n }\n\n document.getElementById(\"fetchGroupDetails\").addEventListener(\"click\", () => {\n const groupId = document.getElementById(\"groupName\").value.trim();\n\n if (!groupId) {\n alert(\"Please select a group.\");\n return;\n }\n\n fetchGroupMembers(groupId);\n });\n\n \n\n</script>"} |