<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">define(["dojo/_base/declare",
  "dojo/_base/lang",
  "dojo/_base/array",
  "dojo/on",
  "dojo/_base/window",
  "dojo/sniff",
  "dojo/dom",
  "dojo/dom-attr",
  "dojo/dom-class",
  "dojo/dom-construct",
  "dojo/dom-style",
  "dojo/topic",
  "app/base/context/app-topics",
  "app/config/app-config",
  "dijit/_WidgetBase",
  "dijit/_TemplatedMixin",
  "dijit/_WidgetsInTemplateMixin",
  "dojo/text!./templates/Dashboard.html",
  "dojo/i18n!app/nls/resources",
  "app/ui/enrich/BaselineModifiers",
  "app/ui/dashboard/Constants",
  "app/ui/dashboard/DashboardItems",
  "app/ui/dashboard/DashboardBar",
  "app/ui/dashboard/ItemPlaceholder",
  "app/ui/dashboard/DashboardSettings",
  "app/ui/dashboard/chart/ChartDialog",
  "app/ui/dashboard/export/ExportToImageSettings",
  "app/base/dashboard/provider/DataProvider",
  "app/base/dashboard/provider/PrimarySources",
  "app/ui/util/_Draggable"],
function(declare, lang, array, on, win, has, dom, domAttr, domClass, domConstruct,
  domStyle, topic, appTopics, appConfig, _WidgetBase, _TemplatedMixin,
  _WidgetsInTemplateMixin, template, i18n, BaselineModifiers, Constants, DashboardItems, DashboardBar,
  ItemPlaceholder, DashboardSettings, ChartDialog, ExportToImageSettings, DataProvider, PrimarySources,
  _Draggable) {

  /*
   * TODO
   *
   *   Dashboard.js var nd = domConstruct.create("div",{"class":"dashboardNode"}, this.targetNodeId);
   *   ComparisonMap.js domConstruct.empty(dom.byId(this.nodeId)); ** empty is commented out
   *
   *   A140 issue
   *   Max-width on modeler dialog title
   *   getHistogramRenderingRule, noData?
   *   ChartEditor label widths for layer selects
   *   secondaryWarning
   *   appTopics.ItemTitleUpdated - auto save
   *
   *   Dashboard should float &amp; resize.
   *   Should non-design sources default to Count?, remove area/perimeter calculations when Count? (performance)
   *   More units? nauticalMiles, yards, squareYards ...
   *   Multiple Assessment Definitions per chart (by design feature subtype)
   *
   *   ChartEditor
   *      if (def.secondary.layer.mapLayerId === null) {
   *        def.secondary = def2.secondary; // TODO keep this to allow for auto-repair?
   *
   *   Compare segment needs testing
   *   TocLayerRemoved needs testing
   *   reclass label topic is in the wrong place?
   *
   *   SelfIntersections
   *   Local area and length calculation?
   *   Issues with CORS and proxy.url
   *   FeatureServiceUtil.serviceAttempts
   *
   *   Histograms: service units (non-meter?)
   *   Histograms: noData?, modelPixelSize, pointBufferDistance, polylineBufferDistance
   *   Histograms: 10.3 services not processing multiple rings?
   *   Histograms: Rob's project that's having noData issues?
   *
   *   tapestry_households htnf_map_3
   *
   *   Project A131
   *   RequestTimeoutError: Timeout exceeded
   *   [url:http://drtest1.esri.com:6080/arcgis/rest/services/phillipines_mosaic/ImageServer]
   *   { message="Timeout exceeded [url:ht...nes_mosaic/ImageServer]",
   *   stack=".cache["dojo/errors/crea...rcgis.com/3.11:214:275\n", response={...}, more...}
   *
   */

  var oThisClass = declare("app.ui.dashboard.Dashboard",
                   [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _Draggable], {

    i18n: i18n,
    templateString: template,

    cssLocation: "dashboard-center",
    targetNodeId: "appMainPage", //"mainMap",
    isVisible: false,
    isRTL: false,
    map: null,

    dataProvider: null,
    primarySources: null,
    kpiSourceStoreTag: "primary",

    _exporter: null,
    _importer: null,

    _globalSettingsDialog: null,
    _windowResizeHandler: null,
    _previousPosition: null,

    postCreate: function() {
      // Set dnd handle
      this._dndHandle = this.headerNode;
      this.inherited(arguments);

      this.isRTL = document.getElementsByTagName("html")[0].getAttribute("dir") === "rtl";

      try {
        if (this.kpiSourceStoreTag === "primary") {
          AppContext.activeProject.dashboardDefinition.reconnect(AppContext.map);
        }
      } catch(ex) {
        console.warn(ex);
      }

      this.primarySources = new PrimarySources({dashboard:this});
      this.itemSelector = this.dashboardBar.itemSelector;

      if (!this.map &amp;&amp; (this.kpiSourceStoreTag === "primary")) this.map = AppContext.map;

      var dashboardCaptionContent = i18n.dashboard.caption;
      if(this.cssLocation === "dashboard-left") {
        if(this.isRTL) {
          this.cssLocation = "dashboard-right";
        }
        dashboardCaptionContent = "&lt;span&gt;" + i18n.dashboard[this.isRTL ? "right" : "left"] + "&lt;/span&gt; " + i18n.dashboard.caption;
      } else if(this.cssLocation === "dashboard-right") {
        if(this.isRTL) {
          this.cssLocation = "dashboard-left";
        }
        dashboardCaptionContent = "&lt;span&gt;" + i18n.dashboard[this.isRTL ? "left" : "right"] + "&lt;/span&gt; " + i18n.dashboard.caption;
      }
      this.dashboardCaption.innerHTML = dashboardCaptionContent;

      domClass.add(this.containerNode,this.cssLocation);
      domStyle.set(this.restoreButton,"display","none");
      this.placeAt(this.targetNodeId);

      this.own(
        on(this.closeButton,"click",lang.hitch(this, function (e) {
          e.stopPropagation();
          e.preventDefault();
          this.hide();
          // domClass.remove(win.body(), this.cssLocation + "-minimized");
        })),

        // on(this.minimizeButton,"click",lang.hitch(this,function(e){
        //   this._minimizeDashboard();
        //   domClass.add(win.body(), this.cssLocation + "-minimized");
        // })),

        on(this.dockButton,"click",lang.hitch(this,function(e){
          this._dockDashboard();
          // domClass.remove(win.body(), this.cssLocation + "-minimized");
        })),

        on(this.restoreButton,"click",lang.hitch(this,function(e){
          this._restoreDashboard();
          // domClass.remove(win.body(), this.cssLocation + "-minimized");
        })),

        on(this.maximizeButton,"click",lang.hitch(this,function(e){
          this._maximizeDashboard();
          // domClass.remove(win.body(), this.cssLocation + "-minimized");
        })),

        on(this.settingsNode,"click",lang.hitch(this,function(e){
          this.globalSettingsClicked();
        })),

        on(this.baselineModifiersNode,"click",lang.hitch(this,function(e){
          this.baselineModifiersClicked();
        })),

        on(this.constantsNode,"click",lang.hitch(this,function(e){
          this.constantsClicked();
        })),

        on(this.addBiNode,"click",lang.hitch(this,function(e){
          this.addNewBiClicked();
        })),

        on(this.addKpiNode,"click",lang.hitch(this,function(e){
          this.addNewKpiClicked();
        })),

        on(this.itemSelector,"ItemChanged",lang.hitch(this,function(info) {
          // TODO needs to work on "before?
          //console.warn(this.id,"ItemChanged",info);
          if (info.hasPrevious) this.previousItemNode.style.visibility = "visible";
          else this.previousItemNode.style.visibility = "hidden";
          if (info.hasNext) this.nextItemNode.style.visibility = "visible";
          else this.nextItemNode.style.visibility = "hidden";
          this.dashboardBar.updateUI(info);
        })),

        topic.subscribe(appTopics.DashboardDefinitionLoading,lang.hitch(this,function(){
          this.itemSelector.deactivatePlaceholder();
          array.forEach(this.items.getChildItems(),function(child){
            child.destroyRecursive(false);
          });
        })),

        topic.subscribe(appTopics.DashboardDefinitionLoaded,lang.hitch(this,function(){
          this.items.createAll();
          this.itemSelector.buildAll(true);
          if (this.isVisible) this._refreshData();
          this.updateSettingsCSS();
        })),

        topic.subscribe(appTopics.DashboardSettingsUpdated,lang.hitch(this,function(){
          this.updateSettingsCSS();
        })),

        topic.subscribe(appTopics.DashboardGeometrySet,lang.hitch(this,function(){
          this.updateSelectionCSS();
        }))
      );

      this.items.createAll();
      this.itemSelector.buildAll(true);

      this.dataProvider = new DataProvider({dashboard:this});
      //this.dataProvider.refreshAll();

      this._restoreActiveItem();
      this.updateSettingsCSS();
      this.updateSelectionCSS();
    },

    destroy: function() {
      if (this.dataProvider) {
        this.dataProvider.destroy();
      }
      if (this.primarySources) {
        this.primarySources.destroy();
      }
      this.inherited(arguments);
    },

    destroyRecursive: function () {
      this._storeActiveItem();
      if (this.dataProvider) {
        this.dataProvider.destroy();
      }
      if (this.primarySources) {
        this.primarySources.destroy();
      }
      this.inherited(arguments);
    },

    /* ----------------------------------------------------------------- */

    addNewBiClicked: function() {
      this.items.addNewBiClicked();
    },

    addNewKpiClicked: function() {
      this.items.addNewKpiClicked();
    },

    baselineModifiersClicked: function() {
      var d = new BaselineModifiers({dashboard:this});
      d.show();
    },

    beforeRestoreSize: function() {},

    clearSelectionGeometry: function() {
      if (AppContext.dashboardGeometry) {
        AppContext.dashboardGeometry = null;
        this.updateSelectionCSS();
        // should clear Map feature selection also
        if (this.isVisible) {
          topic.publish(appTopics.DashboardRequiresRefresh,{});
        }
      }
    },

    constantsClicked: function() {
      var d = new Constants({dashboard:this});
      d.show();
    },

    createChartClicked: function () {
      //var item = this.itemPlaceholder.activeItem;
      //if (item &amp;&amp; item.isDesigner) item.createChartClicked();
      var d = new ChartDialog({dashboard: this});
      d.show();
    },

    exportToImageClicked: function () {
      var d = new ExportToImageSettings({dashboard: this});
      d.show();
    },

    globalSettingsClicked: function() {
      this._globalSettingsDialog = new DashboardSettings();
      this._globalSettingsDialog.show();
    },

    hide: function() {
      this._storeActiveItem();
      this.destroyRecursive(false);
      domClass.remove(win.body(), this.cssLocation + "-opened");
      var dashboardPosition = "left";
      if(this.kpiSourceStoreTag !== "primary") dashboardPosition = "right";
      topic.publish(appTopics.DashboardClosed, {position: dashboardPosition});
    },

    isMaximized: function() {
      return domClass.contains(this.domNode,"maximized");
    },

    // isMinimized: function() {
    //   return domClass.contains(this.domNode,"minimized");
    // },

    isDocked: function() {
      return domClass.contains(this.domNode,"docked");
    },

    isNormalSize: function() {
      return domClass.contains(this.domNode,"normal-size");
    },

    isTocOpened: function() {
      return domClass.contains("appMainPage", "toc-opened");
    },

    nextItemClicked: function() {
      this.itemSelector.activateNext();
    },

    previousItemClicked: function() {
      this.itemSelector.activatePrevious();
    },

    _maximizeDashboard: function() {
      if (!this.isMaximized()) {
        // the storing of the previous position has to happen
        // before ALL class name changes
        if (this.isNormalSize()) {
          this._storePreviousPosition();
        }
        this.itemSelector.deactivatePlaceholder();
        domClass.add(this.domNode,"maximized");
        // maximize from default state
        if (this.isNormalSize()) {
          domClass.remove(this.domNode,"normal-size");
          // calculate new position of the dashboard
          var newPosition = {
            "top": null,
            "left": null,
            "right": null,
            "bottom": "0"
          };
          // put the dashboard at the bottom
          this.reposition(newPosition);
        }
        // maximize from minimize state
        // if (this.isMinimized()) {
        //   domClass.remove(this.domNode,"minimized");
        // }
        if (this.isDocked()) {
          domClass.remove(this.domNode,"docked");
        }
        // resize dashboard
        this.resizeContainerSize();
        // listen to window onResize event to resize dashboard
        if(!this._windowResizeHandler) {
          this.own(this._windowResizeHandler = on.pausable(window,"resize", lang.hitch(this, function(){
            this.resizeContainerSize();
          })));
        } else {
          this._windowResizeHandler.resume();
        }

        this.items.resizeItems();
        this.items.clearDnd();
        this.items.initDnd();
      }
      domStyle.set(this.dockButton,"display","");
      domStyle.set(this.restoreButton,"display","");
      domStyle.set(this.maximizeButton,"display","none");
    },

    // _minimizeDashboard: function() {
    //   if (!this.isMinimized()) {
    //     // the storing of the previous position has to happen
    //     // before ALL class name changes
    //     if (this.isNormalSize()) {
    //       this._storePreviousPosition();
    //     }
    //     domClass.add(this.domNode,"minimized");
    //     // minimize from default state
    //     if (this.isNormalSize()) {
    //       domClass.remove(this.domNode,"normal-size");
    //       // calculate new position of the dashboard
    //       var newPosition = {
    //         "top": null,
    //         "left": null,
    //         "right": null,
    //         "bottom": null
    //       };
    //       // put the dashboard at the bottom
    //       this.reposition(newPosition);
    //     }
    //     // minimize from maximize state
    //     if (this.isMaximized()) {
    //       domClass.remove(this.domNode,"maximized");
    //       this.itemSelector.reactivatePlaceholder();
    //     }
    //   }
    //   domStyle.set(this.minimizeButton,"display","none");
    //   domStyle.set(this.restoreButton,"display","");
    //   domStyle.set(this.maximizeButton,"display","");

    //   // resize dashboard
    //   this.resizeContainerSize();
    //   if(this._stopDraggable) this._stopDraggable();
    //   if(this._windowResizeHandler) this._windowResizeHandler.pause();
    // },

    _dockDashboard: function() { // Work in progress
      if (!this.isDocked()) {
        // the storing of the previous position has to happen
        // before ALL class name changes
        if (this.isNormalSize()) {
          this._storePreviousPosition();
        }
        this.itemSelector.deactivatePlaceholder();
        domClass.add(this.domNode,"docked");
        // dock from default state
        if (this.isNormalSize()) {
          domClass.remove(this.domNode,"normal-size");
          // calculate new position of the dashboard
          var newPosition = {
            "top": null,
            "left": null,
            "right": null,
            "bottom": 0
          };
          // put the dashboard at the bottom
          this.reposition(newPosition);
        }
        // dock from maximize state
        if (this.isMaximized()) {
          domClass.remove(this.domNode,"maximized");
          var newPosition = {
            "top": null,
            "left": null,
            "right": null,
            "bottom": 0
          };
          // put the dashboard at the bottom
          this.reposition(newPosition);
        }
        // resize dashboard
        this.resizeContainerSize();
        // listen to window onResize event to resize dashboard
        if(!this._windowResizeHandler) {
          this.own(this._windowResizeHandler = on.pausable(window,"resize", lang.hitch(this, function(){
            this.resizeContainerSize();
          })));
        } else {
          this._windowResizeHandler.resume();
        }

        if(this._stopDraggable) this._stopDraggable();
        this.items.resizeItems();
      }
      domStyle.set(this.dockButton,"display","none");
      domStyle.set(this.restoreButton,"display","");
      domStyle.set(this.maximizeButton,"display","");
    },

    _positionAtCenter: function() {
      var p = document.getElementById(this.targetNodeId),
          parentWidth = 0,
          dashboardWidth = 0;
      if(!(p &amp;&amp; this.domNode)) return;

      parentWidth = p.getBoundingClientRect().width;
      // TOC opened
      // if(this.isTocOpened) {
      //   parentWidth -=
      // }
      // Split mode
      if(AppContext.activeProject.comparisonSettings.isSplitMode()) {
        parentWidth *= 0.5;
      }
      if(this.domNode) dashboardWidth = this.domNode.getBoundingClientRect().width;
      // right dashboard
      if(this.cssLocation === "dashboard-right")
        this.domNode.style.left = parentWidth + (parentWidth - dashboardWidth) * 0.5 + "px";
      // center or left dashboard
      else
        this.domNode.style.left = (parentWidth - dashboardWidth) * 0.5 + "px";
    },

    _refreshData: function() {
      this.dataProvider.refreshAll();
    },

    _restoreActiveItem: function() {
      try {
        var localId = null;
        if (AppContext.session.dbActiveItems &amp;&amp; AppContext.activeProject.dashboardDefinition &amp;&amp; this.itemSelector) {
          localId = AppContext.session.dbActiveItems[this.kpiSourceStoreTag];
          if (typeof localId !== "undefined" &amp;&amp; localId !== null) {
            array.some(AppContext.activeProject.dashboardDefinition.itemDefinitions,function(def){
              if (localId === def.localId) {
                this.itemSelector.activateItem(def);
                return true;
              }
            }, this);
          }
        }
      } catch(e) {}
    },

    _restoreDashboard: function() {
      // Restore from minimize state
      // if (this.isMinimized()) {
      //   domClass.remove(this.domNode,"minimized");
      // }
      // Restore from minimize state
      if (this.isDocked()) {
        domClass.remove(this.domNode,"docked");
        this.itemSelector.reactivatePlaceholder();
      }
      // Restore from maximize state
      if (this.isMaximized()) {
        domClass.remove(this.domNode,"maximized");
        this.itemSelector.reactivatePlaceholder();
      }
      if (!this.isNormalSize()) {
        domClass.add(this.domNode,"normal-size");
      }
      if (this.itemPlaceholder &amp;&amp; this.itemPlaceholder.activeItem) {
        this.itemPlaceholder.activeItem.resizeItem();
      }
      // domStyle.set(this.minimizeButton,"display","");
      domStyle.set(this.dockButton,"display","");
      domStyle.set(this.restoreButton,"display","none");
      domStyle.set(this.maximizeButton,"display","");

      this.resizeContainerSize();
      this._restorePosition();
      if(this._remakeDraggable) this._remakeDraggable();
      if(this._windowResizeHandler) this._windowResizeHandler.pause();
    },

    _restorePosition: function() {
      if(this._previousPosition) {
        var newPosition = {
          "top": this._previousPosition.top ? this._previousPosition.top : "auto",
          "left": this._previousPosition.left ? this._previousPosition.left : "auto",
          "bottom": this._previousPosition.bottom? this._previousPosition.bottom : "auto",
          "right": "auto"
        };
        this.reposition(newPosition);
        this._previousPosition = null;
      }
    },

    _storeActiveItem: function() {
      try {
        var localId = null;
        if (this.itemPlaceholder &amp;&amp; this.itemPlaceholder.activeItem &amp;&amp; this.itemPlaceholder.activeItem.getDefinition) {
          var d = this.itemPlaceholder.activeItem.getDefinition();
          if (typeof d !== "undefined" &amp;&amp; typeof d.localId !== "undefined") {
            localId = d.localId;
          }
        }
        if (!AppContext.session.dbActiveItems) AppContext.session.dbActiveItems = {};
        AppContext.session.dbActiveItems[this.kpiSourceStoreTag] = localId;
      } catch(e) {}
    },

    _storePreviousPosition: function() {
      // store previous position
      var computedStyles = domStyle.getComputedStyle(this.domNode);
      this._previousPosition =  {
        "top": computedStyles.top,
        "left": computedStyles.left,
        "right": computedStyles.right,
        "bottom": computedStyles.bottom
      };
    },

    show: function() {
      var settings = AppContext.activeProject.dashboardDefinition.settings;
      this.isVisible = true;
      this.domNode.style.display = "";
      if(domClass.contains(this.domNode,"maximized")) {
        this.resizeContainerSize();
        if(this._windowResizeHandler) {
          this._windowResizeHandler.resume();
        }
      }

      this.items.resizeItems();
      if (settings.refreshOnDashboardOpen) {
        this._refreshData();
      }

      // Only position the dashboard at the center of the
      // screen before it has been dragged
      if(!this._dragged) this._positionAtCenter();
      // bring the window to front
      if(this.bringToFront) this.bringToFront();
    },

    toggleVisibility: function() {
      if (this.domNode.style.display === "none") {
        this.show();
      } else {
        this.hide();
      }
    },

    reposition: function(newPosition) {
      if(newPosition) {
        this.domNode.style.top = newPosition.top;
        this.domNode.style.left = newPosition.left;
        this.domNode.style.right = newPosition.right;
        this.domNode.style.bottom = newPosition.bottom;
      }
    },

    resizeContainerSize:function() {
      //console.log(this.items.domNode.clientHeight);
      if(this.items.domNode.clientHeight + this.headerNode.clientHeight &gt; document.body.clientHeight) {
        domClass.add(this.domNode, "fixed");
      }else {
        domClass.remove(this.domNode,"fixed");
      }
    },

    updateSelectionCSS: function() {
      //console.log("updateSelectionCSS");
      try {
        var node = this.domNode;
        if (AppContext.dashboardGeometry) {
          if (AppContext.dashboardGeometry.source === "StudyArea") {
            domClass.add(this.domNode,"activeStudyArea");
            domClass.remove(this.domNode,"featuresSelected");
          } else {
            domClass.add(this.domNode,"featuresSelected");
            domClass.remove(this.domNode,"activeStudyArea");
          }
        } else {
          domClass.remove(this.domNode,"activeStudyArea");
          domClass.remove(this.domNode,"featuresSelected");
        }
      } catch (err) {
        console.error("Error updating dashboard selection CSS");
        console.error(err);
      }
    },

    updateSettingsCSS: function() {
      try {
        var node = this.domNode;
        var settings = AppContext.activeProject.dashboardDefinition.settings;
        if (settings.kpiLayers.useVisibleFeatures) {
          domClass.add(node,"kpi-visible-features");
        } else {
          domClass.remove(node,"kpi-visible-features");
        }
        // settings.nonDesignLayers.useVisibleFeatures
        if (settings.designLayers.useVisibleFeatures) {
          domClass.add(node,"chart-visible-features");
        } else {
          domClass.remove(node,"chart-visible-features");
        }
      } catch (err) {
        console.error("Error updating dashboard settings CSS");
        console.error(err);
      }
    }

  });

  return oThisClass;
});
</pre></body></html>