You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 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.

Code

The code of the script for reference.

projectdoc-inspect-menu.js
/*
 * 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.");
    }
  }
});



  • No labels