- Created by Robert Reiner, last modified on 06. Sep 2020
You are viewing an old version of this page. View the current version.
Compare with Current View Page History
« Previous Version 3 Next »
projectdoc Toolbox
Renders a menu with tools to inspect information from a projectdoc document, shown in the browser.
- Identifier
de.smartics.userscripts.confluence.projectdoc-inspect-menu
- Type
- Repository
- Since
- 1.0
The userscript renders a menu on a Confluence page with tools to inspect the projectdoc document shown in the browser.
It implements the following actions:
- Display Document Properties
- Display Space Properties
- Display Transcluding Documents
Code
The code of the script for reference.
/* * Copyright 2019-2020 Kronseder & Reiner GmbH, smartics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ "use strict"; AJS.toInit(function () { const logToConsole = true; const $propertiesMarker = AJS.$(".projectdoc-document-element.properties"); if (!$propertiesMarker.length) { if (logToConsole) AJS.log("[projectdoc-inspect-menu] Not a projectdoc document. Quitting."); return; } const showDocumentProperties = function () { if(logToConsole) AJS.log("[projectdoc-inspect-menu] Fetching document properties ..."); const pageId = AJS.params.pageId; const locale = AJS.params.userLocale; const baseURL = AJS.params.baseUrl; const htmlTitle = "Page Properties"; let html = "<html lang='" + locale + "'><head><title>" + htmlTitle + "</title><style>" + " .table-sm td, .table-sm th {padding: .1rem !important;}" + " .table td, .table th { font-size: 10px !important;}" + "</style>" + "<link rel=\"stylesheet\"" + " href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\"" + " integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\"" + " crossorigin=\"anonymous\">" + "</head><body><h6>" + htmlTitle + "</h6>"; if(logToConsole) AJS.log("[projectdoc-inspect-menu] Making call ..."); AJS.$.ajax({ url: baseURL + "/rest/projectdoc/1/document/" + pageId + ".json?expand=property&resource-mode=html", async: true, contentType: 'application/json' }).success(function (data) { if(logToConsole) AJS.log("[projectdoc-inspect-menu] Document Properties Data: " + JSON.stringify(data)); html += "<table class=\"table table-sm table-bordered table-striped\">"; AJS.$.each(data["property"], function (index, obj) { html = html + "<tr><th>" + obj.name + "</th><td>" + obj.value + "</td></tr>" } ); html += "</table></body></html>"; const showDialog = window.open('', '', 'width=600,height=800,location=no,toolbar=0'); showDialog.document.body.innerHTML = html; }).error(function (jqXHR, textStatus) { AJS.log("[projectdoc-inspect-menu] Error fetching document properties: " + jqXHR.status + " (" + textStatus + ")"); alert("Failed to fetch document properties: " + jqXHR.status + " (" + textStatus + ")"); }); }; const showSpaceProperties = function () { const spaceKey = AJS.params.spaceKey; const locale = AJS.params.userLocale; const baseUrl = AJS.params.baseUrl; const htmlTitle = "Space Properties for " + spaceKey; let html = "<html lang='" + locale + "'><head><title>" + htmlTitle + "</title><style>" + " .table-sm td, .table-sm th {padding: .1rem !important;}" + " .table td, .table th { font-size: 10px !important;}" + "</style>" + "<link rel=\"stylesheet\"" + " href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\"" + " integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\"" + " crossorigin=\"anonymous\">" + "</head><body><h6>" + htmlTitle + "</h6>"; if(logToConsole) AJS.log("[projectdoc-inspect-menu] Querying Properties Data for Space '" + spaceKey + "' ..."); AJS.$.ajax({ url: baseUrl + "/rest/projectdoc/1/space/" + spaceKey, async: true, dataType: 'json' //contentType: 'application/json' }).success(function (data) { if(logToConsole) AJS.log("[projectdoc-inspect-menu] Space Properties Data: " + JSON.stringify(data)); html += "<table class=\"table table-sm table-bordered table-striped\">"; AJS.$.each(data["property"], function (index, obj) { html = html + "<tr><td>" + obj.source + "</td><th>" + obj.name + "</th><td>" + obj.value + "</td></tr>" } ); html += "</table></body></html>"; const showDialog = window.open('', '', 'width=600,height=800,location=no,toolbar=0'); showDialog.document.body.innerHTML = html; }).error(function (jqXHR, textStatus) { AJS.log("[projectdoc-inspect-menu] Error fetching space properties: " + jqXHR.status + " (" + textStatus + ")"); alert("Failed to fetch space properties: " + jqXHR.status + " (" + textStatus + ")"); }); }; const listTranscludingDocument = function () { const pageId = AJS.params.pageId; const locale = AJS.params.userLocale; const baseUrl = AJS.params.baseUrl; function createPage(i18n, currentDocument, documents) { const htmlTitle = "Transcluding Documents for " + currentDocument[i18n.name]; let html = "<html lang='" + locale + "'><head><title>" + htmlTitle + "</title><style>" + " body {margin: 1rem !important;}" + " .table-sm td, .table-sm th {padding: .1rem !important;}" + " .table td, .table th { font-size: .8rem !important;}" + "</style>" + "<link rel=\"stylesheet\"" + " href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\"" + " integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\"" + " crossorigin=\"anonymous\">" + "</head><body><h3>" + htmlTitle + "</h3>"; html += "<table class=\"table table-sm table-bordered table-striped\">"; const hitCount = documents.document.length; const tinyUrlName = i18n["tinyUrl"] + '\u00a7'; html += "<p>Content of document '<a href='" + currentDocument[tinyUrlName] + "'>" + currentDocument[i18n.name] + "</a>' is transcluded by "; if (hitCount === 0) { html += "no document.</p>"; } else if (hitCount === 1) { html += "one document.</p>"; } else { html += hitCount + " documents.</p>"; } $.each(documents.document, function (index, doc) { const current = {}; $.each(doc.property, function (i, property) { current[property.name] = property.value; }); const name = current[i18n.name]; const shortDescription = current[i18n.shortDescription]; const url = current[tinyUrlName]; html = html + "<tr><th><a href='" + url + "'>" + name + "</a></th><td>" + shortDescription + "</td></tr>"; } ); html += "</table></body></html>"; return html; } if(PDBMLS) { const i18n = PDBMLS.fetchI18n(baseUrl, ["title", "spaceKey", "name", "shortDescription", "tinyUrl"]); const tinyUrlName = i18n["tinyUrl"]; const currentDocument = PDBMLS.fetchDocument(baseUrl, pageId, [i18n.spaceKey, i18n.title, i18n.name, tinyUrlName]); if (currentDocument) { const spaceKey = currentDocument[i18n.spaceKey]; const title = currentDocument[i18n.title]; const pageReference = spaceKey + "." + title; const where = "$<TranscludedDocumentTitles>=[" + pageReference + "]"; const documents = PDBMLS.fetchDocuments(baseUrl, [i18n.name, i18n.shortDescription, tinyUrlName], where); let html = createPage(i18n, currentDocument, documents); const container = window.open('', '', 'width=600,height=800,location=no,toolbar=0'); container.document.body.innerHTML = html; } } else { AJS.log("[projectdoc-inspect-menu] Error transcluding documents. PDBMLS service of Bookmarklets Extension not found."); alert("Failed to transcluding documents: PDBMLS service of Bookmarklets Extension not found."); } }; if (logToConsole) AJS.log("[projectdoc-inspect-menu] Adding menu ..."); const createMenu = function () { const $rootEntry = AJS.$("<div id='projectdoc-menu-inspect'></div>"); $rootEntry.addClass("aui-buttons"); const $menu = AJS.$("<button id='projectdoc-menu-inspect-button'></button>"); $menu.addClass("aui-button aui-dropdown2-trigger"); $menu.attr("aria-controls", "projectdoc-menu-inspect-dropdown"); $rootEntry.append($menu); $menu.text("Inspect"); const $dropdown = AJS.$("<aui-dropdown-menu id=\"projectdoc-menu-inspect-dropdown\">"); $menu.append($dropdown); const $propertiesSection = AJS.$("<aui-section label=\"Properties\">"); $dropdown.append($propertiesSection); const $menuItemDocumentProperties = AJS.$("<aui-item-link id='projectdoc-menu-inspect-item-document-properties' href=\"#document-properties\"></aui-item-link>"); $menuItemDocumentProperties.text("Show document properties"); $menuItemDocumentProperties.on("click", function (event) { event.preventDefault(); showDocumentProperties(); }); $propertiesSection.append($menuItemDocumentProperties); const $menuItemSpaceProperties = AJS.$("<aui-item-link id='projectdoc-menu-inspect-item-space-properties' href=\"#space-properties\"></aui-item-link>"); $menuItemSpaceProperties.text("Show space properties"); $menuItemSpaceProperties.on("click", function (event) { event.preventDefault(); showSpaceProperties(); }); $propertiesSection.append($menuItemSpaceProperties); const $menuItemTransclusions = AJS.$("<aui-item-link id='projectdoc-menu-inspect-item-transclusions' href=\"#transclusions\"></aui-item-link>"); $menuItemTransclusions.text("Show transclusions"); $menuItemTransclusions.on("click", function (event) { event.preventDefault(); listTranscludingDocument(); }); $propertiesSection.append($menuItemTransclusions); return $rootEntry; } const getParentWith = function ($rootElement, tagName) { let $parent = $rootElement.parent(); while ($parent !== undefined) { if (logToConsole) AJS.log("[projectdoc-inspect-menu] Found parent '" + $parent.prop('tagName') + "'."); if ($parent.prop('tagName') === tagName) { if (logToConsole) AJS.log("[projectdoc-inspect-menu] Parent is matching."); return $parent; } $parent = $parent.parent(); } }; const $createButton = AJS.$('#create-page-button'); if ($createButton.length) { if (logToConsole) AJS.log("[projectdoc-inspect-menu] Found create button on page."); const $navContainer = getParentWith($createButton, "UL"); if ($navContainer) { if (logToConsole) AJS.log("[projectdoc-inspect-menu] Found navigation container on page."); const $projectdocMenu = createMenu(); $navContainer.append($projectdocMenu); } else { AJS.log("[projectdoc-inspect-menu] No navigation container found on page to add menu. No menu is added."); } } });
Details
More information on using this userscript.
Rendering
The inspect menu is rendered next to the create button in the Confluence toolbar.
Requirements
The script requires the following apps to be installed on Confluence.
- The projectdoc Toolbox for Atlassian Confluence
- The projectdoc Toolbox supports agile teams in writing project documentation collaboratively. This is an introduction to use cases for and features of the projectdoc Toolbox.
- Web API Extension
- Add-on to extend projectdoc with an API to access on the web.
- Bookmarklets Extension
- Add-on to extend the Toolkit with Bookmarklets. Allows to execute tools via the browser.
Limitations
There is an issue with the calculation of the URLs to transcluding pages.
Resources
More information on this topic is available by the following resources.
- Display Document Properties
- Displays the document properties of the projectdoc document currently shown in the browser.
- Display Space Properties
- Displays the space properties of the projectdoc document's space currently shown in the browser.
- List Transcluding Documents
- Shows the list of documents that transclude content from the current document.
- No labels