Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • auth-signatures
  • feature/backendAbstraction
  • feature/GeneralLdpClient
  • feature/eslint
  • feature/AdvancedLdpClient
  • 0.1.5
  • 0.1.4
  • 0.1.3
  • 0.1.2
  • 0.1.1
  • 0.1.0
  • 0.0.2
  • 0.0.1
14 results

candidate_cycles.PNG

Blame
  • Forked from DBIS / FactDAG / factlib.js
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    utils.js 7.06 KiB
    import "gridstack/dist/gridstack.min.css";
    import { GridStack } from "gridstack";
    
    /**
     * Request analytics engine results from rights engine.
     * @param {*} token
     * @param {*} url
     * @returns
     */
    export async function getResult(token, url) {
      try {
        const response = await fetch(url, {
          headers: {
            Authorization: `Basic ${token}`,
          },
        });
        return await response.json();
      } catch (error) {
        throw Error("Fetching result from backend failed. Please check URL and TOKEN settings.");
      }
    }
    
    /**
     * Plots chart in each configured widget.
     * @param {*} nodes
     * @param {*} widgets
     */
    function plotWidgets(nodes, widgets) {
      for (const node of nodes) {
        if (node.subGrid) {
          // Handle sub grid
          plotWidgets(node.subGrid.engine.nodes, widgets);
        } else {
          const widget = widgets[node.widgetId];
          if (widget) {
            plot(node, widget);
          } else if (node.el.getAttribute("widgetId")) {
            const widgetId = node.el.getAttribute("widgetId");
            plot(node, widgets[widgetId]);
          } else {
            console.error(`Couldn't find widget by id ${node.widgetId}`);
          }
        }
      }
    }
    
    /**
     * Calls plot function on each widget, passing current widget div container width, height and
     * updates widget content with resulting chart svg.
     * @param {*} node
     * @param {*} widget
     */
    function plot(node, widget) {
      const content = node.el.querySelector(".grid-stack-item-content");
      const width = content.offsetWidth;
      const height = content.offsetHeight;
      content.innerHTML = widget.plot(width, height);
    }
    
    /**
     * Renders single widget content for available widgets sidebar.
     * @param {*} widget
     * @param {*} widgetId
     * @returns
     */
    function createAvWidgetPlaceholder(widget, widgetId) {
      const content = widget.plot(400, 400);
      const div = document.createElement("div");
      div.innerHTML = `<div class="newWidget grid-stack-item" widgetId="${widgetId}"><div class="grid-stack-item-content">${content}</div></div>`;
      return div;
    }
    
    /**
     * Renders all available widgets in sidebar.
     * @param {*} widgets
     */
    export function drawAvailableWidgets(widgets) {
      const availableWidgets = document.getElementById("available-widgets");
      for (const widgetId of Object.keys(widgets)) {
        const avWidgetDiv = createAvWidgetPlaceholder(widgets[widgetId], widgetId);
        availableWidgets.appendChild(avWidgetDiv, widgetId);
      }
    }
    
    /**
     * Handles widget drag in from sidebar by adding a widget to the widgets grid.
     * @param {*} event
     * @returns
     */
    export function handleNewWidgetDragIn(event) {
      const parentWithClass = event.srcElement.closest(".newWidget");
      const targetEl = parentWithClass.cloneNode(true);
      targetEl.style.removeProperty("newWidget");
      return targetEl;
    }
    
    /**
     * Removes all child nodes from an HTML node.
     * @param {*} parent
     */
    function removeAllChildNodes(parent) {
      while (parent.firstChild) {
        parent.removeChild(parent.firstChild);
      }
    }
    
    /**
     * Initial widgets grid
     * @param {*} widgets
     * @param {*} items
     */
    export function initGrid(widgets, items) {
      // Basic grid object
      const grid = GridStack.init({
        cellHeight: 70,
        acceptWidgets: true,
        removable: ".dropzone-remove",
        minRow: 2,
        subGrid: {
          disableOneColumnMode: true,
          minRow: 2,
          cellHeight: 70,
          margin: 5,
          acceptWidgets: true, // will accept .grid-stack-item by default
          locked: true,
          noResize: true,
          noMove: true,
          removable: ".dropzone-remove",
        },
        subGridDynamic: true,
      });
    
      // Enables widget resize and movement on grid
      function enableWidgetMoveAndResize() {
        grid.enableResize(true);
        grid.enableMove(true);
    
        grid.engine.nodes.map((e) => {
          if (e.subGrid) {
            e.subGrid.enableResize(true);
            e.subGrid.enableMove(true);
          }
        });
      }
    
      // Disables widget resize and movement on grid
      function disableWidgetMoveAndResize() {
        grid.enableResize(false);
        grid.enableMove(false);
    
        grid.engine.nodes.map((e) => {
          if (e.subGrid) {
            e.subGrid.enableResize(false);
            e.subGrid.enableMove(false);
          }
        });
      }
    
      grid.load(items);
      grid.setAnimation(false);
      addResizeListener(grid);
    
      plotWidgets(grid.engine.nodes, widgets);
      disableWidgetMoveAndResize();
    
      // Add resize listener for subgrid
      grid.engine.nodes.map((e) => {
        if (e.subGrid) {
          e.subGrid.on("resizestop", function (event, el) {
            plotWidgets(grid.engine.nodes, widgets);
          });
        }
      });
    
      // Rerender all widgets on widget removal
      grid.on("removed change", function (e, items) {
        plotWidgets(grid.engine.nodes, widgets);
      });
    
      // Rerender all widgets when adding a new widget
      grid.on("added", function (e, items) {
        plotWidgets(grid.engine.nodes, widgets);
      });
    
      // Create resize event listener and rerenders all widgets on resize
      function addResizeListener(grid) {
        window.addEventListener(
          "resize",
          function (event) {
            plotWidgets(grid.engine.nodes, widgets);
          },
          true
        );
      }
    
      /**
       * Handle sidebar toggle, including enabeling/disabeling widget resize and movement.
       */
      function toggleSidebar() {
        const sidebar = document.getElementById("sidebar");
        const isVisible = sidebar.className === "sidebar";
        if (isVisible) {
          disableWidgetMoveAndResize();
          sidebar.className = "sidebar-hidden";
          const avWidgets = document.getElementById("available-widgets");
          removeAllChildNodes(avWidgets);
          plotWidgets(grid.engine.nodes, widgets);
        } else {
          sidebar.className = "sidebar";
          drawAvailableWidgets(widgets);
          GridStack.setupDragIn(".newWidget", {
            revert: "invalid",
            scroll: false,
            appendTo: "body",
            helper: handleNewWidgetDragIn,
          });
    
          enableWidgetMoveAndResize();
          plotWidgets(grid.engine.nodes, widgets);
        }
      }
    
      /**
       * Saves current grid configuration. The returned grid configuration can be loaded later (e.g. when the user revisited the dashboard).
       * @returns grid configuration
       */
      function save() {
        const oldGrid = grid.save();
        return oldGrid.map((item) => {
          if (item.subGrid) {
            return {
              x: item.x,
              y: item.y,
              w: item.w,
              h: item.h,
              subGrid: {
                x: item.subGrid.x,
                y: item.subGrid.y,
                w: item.subGrid.w,
                h: item.subGrid.h,
                children: item.subGrid.children.map((e) => ({
                  x: e.x,
                  y: e.y,
                  w: e.w,
                  h: e.h,
                  widgetId: e.widgetId,
                })),
              },
            };
          } else {
            return {
              x: item.x,
              y: item.y,
              w: item.w,
              h: item.h,
              widgetId: item.widgetId,
            };
          }
        });
      }
    
      /**
       * Loads a grid configuration. Should be used along with the save function.
       * @param {*} items
       */
      function load(items) {
        grid.removeAll();
        grid.load(items);
        plotWidgets(grid.engine.nodes, widgets);
        disableWidgetMoveAndResize();
      }
    
      return {
        grid,
        toggleSidebar,
        save,
        load,
        enableWidgetMoveAndResize,
        disableWidgetMoveAndResize,
      };
    }