Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

version10

...

  1. Edit Confluence page, add HTML Macro for Confluence or Advanced Macro for Confluence to your page

...

  1. The macro editor will be opened. Copy & paste below code to the macro and adjust it based on your requirement.

Code Block
languagejs

<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" border="1" style="width: 100%; border-collapse:  {\ncollapse;">
                <thead>
       \"displayName\": \"John Doe\",\n       <tr>
                \"emailAddress\": \"john@example.com\"\n    <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>

  1. Publish your page and see the result:

Advanced html
version15
{"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       },\n     else if(groupId == 2){\n            {\n    groupMembers = [\n                  \"displayName\": \"Jane Smith\", {\n                        \"emailAddressdisplayName\": \"janeĢ€@example.comBob Johnson\",\n                    },\n                    {\"emailAddress\": \"bob@example.com\",\n                        \"displayNameprofilePicture\": \"Alice Brown\",\n{\n                            \"emailAddresspath\": \"alice@example.comhttps://icon-library.com/images/user-png-icon/user-png-icon-5.jpg\"\n                        }\n                   ]; },\n            }\n        {\n     else if(groupId == 2){\n                groupMembers = [\"displayName\": \"Charlie White\",\n                    {    \"emailAddress\": \"charlie@example.com\",\n                        \"displayNameprofilePicture\": \"Bob Johnson\",\n{\n                            \"emailAddresspath\": \"bob@example.com\"https://icon-library.com/images/user-image-icon/user-image-icon-10.jpg\"\n                        },\n                    {}\n                ];\n         \"displayName\": \"Charlie White\",\n   }\n            else{\n                 \"emailAddress\": \"charlie@example.com\"\groupMembers = [\n                    }{\n                ];\n        \"displayName\":    }\"David Black\",\n            else{\n            \"emailAddress\": \"david@example.com\",\n   groupMembers = [\n                   \"profilePicture\": {\n                            \"displayNamepath\": \"David Black\",https://icon-library.com/images/icon-for-user/icon-for-user-1.jpg\"\n                        \"emailAddress\": \"david@example.com\"\ }\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>                \n                    <th>Name</th>\n                    <th>Email</th>\n                </tr>\n                </thead>\n                <tbody>\n                `;\n\n        for (const member of groupMembers) {\n\n            let img = `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n            img = member.profilePicture?.path;\n            if (!img) {\n                img = `https://www.gravatar.com/avatar/${member.emailAddress}?s=32&d=identicon`;\n            }\n            else{\n                if(!img.startsWith(\"http\")){\n                    img = `${AP._hostOrigin}/${img}`;\n                }\n            }\n            table += `\n                        <tr>\n                            <td><img style=\"width:20px32px; hight:20px32px;\" 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>"}