...
version | 8 |
---|
...
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\">\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 <script> \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(if(groups.length === 0){\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 data = JSON.parse(response.body);\n\n if (!data.results || data.results.length === 0) { \n break;\n }\n\n groupMembers = groupMembers.concat(data.results);\n url = data._links.next; \n\n } catch (error) {\n console.error(\"Error:\", error);\n groupDetailsDiv.textContent = \"Failed to fetch group members. Check the console for details.\";\n url = undefined;\n }\n }\n\n if (groupMembers.length === 0) {\n //groupDetailsDiv.textContent = \"No members found for this group.\";\n //return;\n if(groupId == 1){ } \n // Build and display the table let groupMemberstable = [\n` <table class="aui" {\n border="1" style="width: 100%; border-collapse: collapse;"> <thead> \"displayName\": \"John Doe\",\n <tr> \"emailAddress\": \"john@example.com\"\n <th></th> },\n {\n <th>Name</th> \"displayName\": \"Jane Smith\",\n<th>Email</th> </tr> \"emailAddress\": \"janeĢ@example.com\"\n </thead> },\n <tbody> {\n`; for (const member of groupMembers) { \"displayName\": \"Alice Brown\",\n let img = `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`; img \"emailAddress\": \"alice@example.com\"\n= member.profilePicture?.path; if (!img) { }\n img ];\n= `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`; }\n else{ if(groupId == 2){\n groupMembers = [\nif(!img.startsWith("http")){ img = {\n`${AP._hostOrigin}/${img}`; } \"displayName\": \"Bob Johnson\",\n } table += ` \"emailAddress\": \"bob@example.com\"\n <tr> },\n {\n <td><img style="width:32px; hight:32px;" src="${img}" alt="Avatar"></td> \"displayName\": \"Charlie White\",\n <td>${member.displayName}</td> \"emailAddress\": \"charlie@example.com\"\n <td>${member.emailAddress || }\n"N/A"}</td> ];\n }\n else{\n </tr> groupMembers = [\n {\n`; } table += \"displayName\": \"David Black\",\n"</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 data = JSON.parse(response.body);\n\n if (!data.results || data.results.length === 0) { \n break;\n }\n\n groupMembers = groupMembers.concat(data.results);\n url = data._links.next; \n\n } catch (error) {\n console.error(\"Error:\", error);\n groupDetailsDiv.textContent = \"Failed to fetch group members. Check the console for details.\";\n url = undefined;\n }\n }\n\n if (groupMembers.length === 0) {\n //groupDetailsDiv.textContent = \"No members found for this group.\";\n //return;\n if(groupId == 1){ // Hardcoded group members for testing \n groupMembers = [\n {\n \"displayName\": \"John Doe\",\n \"emailAddress\": \"john@example.com\",\n \"profilePicture\": {\n \"path\": \"https://icon-library.com/images/admin-user-icon/admin-user-icon-4.jpg\"\n }\n },\n {\n \"displayName\": \"Jane Smith\",\n \"emailAddress\": \"jane@example.com\",\n \"profilePicture\": {\n \"path\": \"https://icon-library.com/images/google-user-icon/google-user-icon-11.jpg\"\n }\n },\n {\n \"displayName\": \"Alice Brown\",\n \"emailAddress\": \"alice@example.com\",\n \"profilePicture\": {\n \"path\": \"https://icon-library.com/images/user-icon-png/user-icon-png-29.jpg\"\n }\n }\n ];\n }\n else if(groupId == 2){\n groupMembers = [\n {\n \"displayName\": \"Bob Johnson\",\n \"emailAddress\": \"bob@example.com\",\n \"profilePicture\": {\n \"path\": \"https://icon-library.com/images/user-png-icon/user-png-icon-5.jpg\"\n }\n },\n {\n \"displayName\": \"Charlie White\",\n \"emailAddress\": \"charlie@example.com\",\n \"profilePicture\": {\n \"path\": \"https://icon-library.com/images/user-image-icon/user-image-icon-10.jpg\"\n }\n }\n ];\n }\n else{\n groupMembers = [\n {\n \"displayName\": \"David Black\",\n \"emailAddress\": \"david@example.com\",\n \"profilePicture\": {\n \"path\": \"https://icon-library.com/images/icon-for-user/icon-for-user-1.jpg\"\n }\n }\n ];\n }\n }\n\n // Build and display the table\n let table = `\n <table class=\"aui\" border=\"1\" style=\"width: 100%; border-collapse: collapse;\">\n <thead>\n <tr>\n <th></th> \"emailAddress\": \"david@example.com\"\n }<th>Name</th>\n ];\n <th>Email</th>\n }\n }</tr>\n\n // Build and display the table</thead>\n let table = `\n <tbody>\n <table class=\"aui\" border=\"1\" style=\"width: 100%; border-collapse: collapse`;\">n\n for (const member of <thead>groupMembers) {\n\n let img <tr>= `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n img = member.profilePicture?.path;\n <th></th> if (!img) {\n img <th>Name</th>\n <th>Email</th>= `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n </tr>}\n </thead>else{\n <tbody>if(!img.startsWith(\"http\")){\n `;\n\n img for (const member of groupMembers) {\n\n= `${AP._hostOrigin}/${img}`;\n let img = `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n img = member.profilePicture?.path || img;}\n table += `\n <tr>\n <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 </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>"} |