Commit fd7d7395 authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Replantea diseño Details y extensión _Window

Limpia código no usado y corrige multitud de lógicas. Corrige usos por
parte de otros módulos tras estos cambios.

Todavía quedan casos que controlar para que el funcionamiento sea el
mismo, como el contenido del popup de recolección de basuras en la
sección de gráficas, que no se muestran la primera vez.
parent 07d0f567
Loading
Loading
Loading
Loading
+88 −124
Original line number Diff line number Diff line
@@ -43,18 +43,21 @@ define([
				hiddenClass: "hidden",
				noScroll: false,

				_relativeRowsClass: "data-percentage-rows",
				_fixedRowsClass: "data-rows",
				_relativeRowsParameterName: "data-percentage-rows",
				_fixedRowsParameterName: "data-rows",
				_colsParameterName: "data-cols",
				_updateInteractiveTimeout: 100,

				_widgets: {},
				_widgetsShowWindows: {},
				_nodes: {}
				_nodes: {},
				_nodesHandlers: {}
			};

			lang.mixin(this, this.config, args);
		},

		// TODO: este método es más propio de vista que de diseño, el diseño puede usarse a nivel más bajo que una vista
		_putMetaTags: function() {
			//	summary:
			//		Manda a publicar la información necesaria para que se generen las meta-tags
@@ -94,16 +97,11 @@ define([
		_setControllerOwnCallbacksForEvents: function() {

			this._onEvt('ME_OR_ANCESTOR_SHOWN', lang.hitch(this, this._onControllerMeOrAncestorShown));
			this._onEvt('RESIZE', lang.hitch(this, this._subParentResized));
			this._onEvt('RESIZE', lang.hitch(this, this._onControllerResize));
			this._onEvt('LAYOUT_COMPLETE', lang.hitch(this, this._onLayoutComplete));
			this._onEvt('BUTTON_EVENT', lang.hitch(this, this._onButtonEvent));
		},

		_afterShow: function(request) {

			this.startup();
		},

		_afterControllerShow: function() {

			if (!this._widgetsAlreadyGenerated) {
@@ -115,26 +113,26 @@ define([
		_generateWidgets: function() {

			for (var key in this.widgetConfigs) {
				this._widgetsAlreadyGenerated = true;
				var config = this.widgetConfigs[key];
				var config = this.widgetConfigs[key] || {};
				this._createWidget(key, config);
			}

			this._widgetsAlreadyGenerated = true;
		},

		_buildVisualization: function() {

			this._windowContainersAlreadyShown = null;

			this._classRow = this.noScroll ? this._relativeRowsClass : this._fixedRowsClass;
			this._rowsParameterName = this.noScroll ? this._relativeRowsParameterName : this._fixedRowsParameterName;

			for (var key in this.widgetConfigs) {
				this._widgetVisualization(key);
				this._buildWidgetVisualization(key);
			}

			// TODO: hacer esto cuando todos los widgets hayan informado de que están listos (array de dfd)
			this._updateInteractive();
		},

		_widgetVisualization: function(key) {
		_buildWidgetVisualization: function(key) {

			var config = this.widgetConfigs[key];

@@ -142,19 +140,18 @@ define([
				return;
			}

			this._createBox(key, config);

			this._showWidget(key, config);
			this._createWidgetNode(key, config);

			this._makeNodeInteractive(this._nodes[key]);
			this._showWidget(key);
		},

		_subParentResized: function() {
		_onControllerResize: function() {

			this._getShown() && this._updateInteractive();
		},

		_onButtonEvent: function(evt) {
			// TODO: eso es para casos concretos, debería separarse

			var methodName = "_" + evt + "Clicked";
			this[methodName] && this[methodName](evt);
@@ -167,6 +164,7 @@ define([
		},

		_checkPathVariableId: function() {
			// TODO: este método es más propio de vista que de diseño, el diseño puede usarse a nivel más bajo que una vista

			if (!this.pathVariableId) {
				this._goTo404();
@@ -175,7 +173,6 @@ define([

		_onControllerMeOrAncestorShown: function() {

			this._emitEvt("RESIZE");
			this._updateInteractive();
		},

@@ -198,126 +195,130 @@ define([
			return condition && !!this.data[condition];
		},

		_getWidgetInstance: function(key) {

			return this._widgets[key];
		},

		_createWidget: function(key, config) {

			if (this._widgets[key]) {
			if (this._getWidgetInstance(key)) {
				return;
			}

			if (!config.props) {
				config.props = {};
			}

			config.props = this._merge([this.propsWidget || {}, config.props]);
			config.props.ownChannel = key;
			config.props.parentChannel = this.getChannel();
			var moduleProps = this._merge([this.propsWidget || {}, config.props || {}]);
			moduleProps.ownChannel = key;
			moduleProps.parentChannel = this.getChannel();

			var module = this._widgets[key] = new declare(config.type).extend(_Window)(config.props);
			var moduleType = config.type,
				moduleDefinition = declare(moduleType).extend(_Window),
				moduleInstance = new moduleDefinition(moduleProps);

			this._listenModule(module);
			this._widgets[key] = moduleInstance;
			this._listenModule(moduleInstance);
		},

		_listenModule: function(module) {
		_listenModule: function(moduleInstance) {

			this._setSubscription({
				channel: module.getChannel("RESIZED"),
				channel: moduleInstance.getChannel("RESIZED"),
				callback: "_subModuleResized"
			});
		},

		_createBox: function(key, config) {
		_createWidgetNode: function(key, config) {

			var node = this._nodes[key] = put("div." + this.hiddenClass + "[" + this._classRow + "=" +
				config.height + "][data-cols=" + config.width + "]");
			var rows = config.height || 1,
				cols = config.width || 1,
				nodeParams = "[" + this._rowsParameterName + "=" + rows + "][" + this._colsParameterName + "=" + cols +
					"]",
				node = put("div." + this.hiddenClass + nodeParams);

			this._nodes[key] = node;

			put(this.centerNode, node);
		},

		_showWidget: function(key, config) {
		_showWidget: function(key) {

			var module = this._widgets[key],
			var instance = this._getWidgetInstance(key),
				node = this._nodes[key];

			this._publish(module.getChannel("SHOW"), {
				node: node
			});

			put(node, "!hidden");
		},

		_showWidgets: function() {

			for (var key in this._widgets) {
				this._showWidget(key);
			if (!instance || !node) {
				return;
			}
		},

		_connectAndShowWidgetAndWindow: function(key) {

			this._connectWidget(key);
			this._showWidget(key);
			this._showWindow(key);
		},
			this._once(instance.getChannel("SHOWN"), lang.hitch(this, function(key, node) {

		_hideWidget: function(key) {

			var module = this._widgets[key],
				node = this._nodes[key];
				put(node, "!" + this.hiddenClass);
				this._addWidgetInteractivity(key);
			}, key, node));

			this._publish(module.getChannel("HIDE"), {
			this._publish(instance.getChannel("SHOW"), {
				node: node
			});

			put(node, ".hidden");
		},

		_hideWidgets: function() {
		_hideWidget: function(key) {

			var instance = this._getWidgetInstance(key),
				node = this._nodes[key];

			for (var key in this._widgets) {
				this._hideWidget(key);
			if (!instance || !node) {
				return;
			}
		},

		_hideAndDisconnectWidget: function(key) {
			this._once(instance.getChannel("HIDDEN"), lang.hitch(this, function(node) {

				put(node, "." + this.hiddenClass);
			}, node));

			this._hideWidget(key);
			this._disconnectWidget(key);
			this._publish(instance.getChannel("HIDE"), {
				node: node
			});
		},

		_connectWidget: function(key) {

			var module = this._widgets[key];
			var instance = this._getWidgetInstance(key);

			this._publish(module.getChannel("CONNECT"));
			this._publish(instance.getChannel("CONNECT"));
		},

		_disconnectWidget: function(key) {

			var module = this._widgets[key];
			var instance = this._getWidgetInstance(key);

			this._publish(module.getChannel("DISCONNECT"));
			this._publish(instance.getChannel("DISCONNECT"));
		},

		_makeNodeInteractive: function(node) {
		_addWidgetInteractivity: function(key) {

			if (this._nodesHandlers[key]) {
				return;
			}

			var widgetNode = this._nodes[key];
			if (widgetNode) {
				this._nodesHandlers[key] = this._addNodeInteractivity(widgetNode);
			}
		},

			put(node, '!' + this.hiddenClass);
		_addNodeInteractivity: function(node) {

			this.packery.addItems(node);

			var widthStep = this.centerNode.offsetWidth * (1 / 6) - 2.555,
			var widthStep = this.centerNode.offsetWidth * (1 / 6),// - 2.555,
				draggie = new draggabilly(node, {
					handle: ".windowTitle",
					grid: [ widthStep, 100 ]
				});

			draggie.on("dragStart", lang.hitch(this, function() {

				this._dragStart = true;
			}));

			draggie.on("dragEnd", lang.hitch(this, this._updateInteractive));

			this.packery.bindDraggabillyEvents(draggie);

			return draggie;
		},

		_subModuleResized: function() {
@@ -334,16 +335,11 @@ define([

		_onLayoutComplete: function(laidOutItems) {

			if (!this._windowContainersAlreadyShown) {
				this._showWindowContainers();
			}

			var totalHeight = this.centerNode.scrollHeight,
				totalWidth = this.centerNode.scrollWidth;
				totalWidth = this.centerNode.scrollWidth,
				sizeHasChanged = this._oldTotalHeight !== totalHeight || this._oldTotalWidth !== totalWidth;

			if (this._dragStart || this._oldTotalHeight !== totalHeight || this._oldTotalWidth !== totalWidth) {
				this._dragStart = false;
				this._updateInteractive();
			if (sizeHasChanged) {
				this._emitEvt("RESIZE");
			}

@@ -353,40 +349,8 @@ define([
			this._emitEvt("LOADED");
		},

		_showWindowContainers: function() {

			this._windowContainersAlreadyShown = true;

			for (var key in this._widgets) {
				if (!this._widgetsShowWindows[key]) {
					this._widgetsShowWindows[key] = true;
					this._showWindow(key);
				}
			}
		},

		_showWindow: function(key) {

			var module = this._widgets[key];

			this._publish(module.getChannel('SHOW_WINDOW'));
		},

		_resizeWindowContainers: function() {

			for (var key in this._widgets) {
				this._resizeWindowContainer(key);
			}
		},

		_resizeWindowContainer: function(key) {

			var module = this._widgets[key];

			this._publish(module.getChannel('RESIZE'));
		},

		_reportClicked: function() {
			// TODO: eso es para casos concretos, debería separarse

			this._publish(this._buildChannel(this.taskChannel, this.actions.GET_REPORT), {
				target: this.selectionTarget ? this.selectionTarget : this.target,
+0 −4
Original line number Diff line number Diff line
@@ -357,8 +357,6 @@ define([
				toInitValues: true,
				node: this._nodes[label]
			});

			this._publish(form.getChannel('SHOW_WINDOW'));
		},

		_showBoxUser: function(target) {
@@ -375,8 +373,6 @@ define([
			this._publish(instanceWidget.getChannel("SHOW"), {
				node: this._nodes[label]
			});

			this._publish(instanceWidget.getChannel('SHOW_WINDOW'));
		},

		_subscriptionOnceChangeImage: function() {
+9 −7
Original line number Diff line number Diff line
@@ -173,12 +173,13 @@ define([

		_needToHideOrShowWidgets: function(data) {

			var i;
			var i, widgetKey;

			if (this._lastDataLength && this._lastDataLength > data.length) {
				//this._hideAndDisconnectWidget("linearChartsContainer");
				for (i = data.length; i < this._lastDataLength; i++) {
					this._hideAndDisconnectWidget("multiPieChartContainer" + i);
					widgetKey = "multiPieChartContainer" + i;
					this._hideWidget(widgetKey);
					this._disconnectWidget(widgetKey);
				}

				this._lastWidgetsShow = {
@@ -186,16 +187,17 @@ define([
					size: this._lastDataLength - data.length
				};

				this._updateInteractive();
				//this._updateInteractive();
			} else if (this._lastWidgetsShow) {
				//this._connectAndShowWidgetAndWindow("linearChartsContainer");
				for (i = this._lastWidgetsShow.i; i <= this._lastWidgetsShow.size; i++) {
					this._connectAndShowWidgetAndWindow("multiPieChartContainer" + i);
					widgetKey = "multiPieChartContainer" + i;
					this._connectWidget(widgetKey);
					this._showWidget(widgetKey);
				}

				this._lastWidgetsShow = null;

				this._updateInteractive();
				//this._updateInteractive();
			}
		},

+24 −108
Original line number Diff line number Diff line
define([
	"dojo/_base/lang"
	, "dojo/Deferred"
	, "dojo/dom-attr"
	, "dojo/dom-class"
	, "dojo/dom-style"
	, "dojo/promise/all"
	, "put-selector/put"
	, "templates/LoadingArrows"
], function(
	lang
	, Deferred
	, domAttr
	, domClass
	, domStyle
	, all
	, put
	, LoadingTemplate
) {

	return {
		//	summary:
		//		Extensión para asignar una ventana a los módulos con visualización.
@@ -27,13 +22,6 @@ define([

		minWidth: 200,

		loadingClass: "loadingWrapper",
		loadingAttr: "loading",

		windowActions: {
			SHOW_WINDOW: "showWindow"
		},

		postCreate: function() {

			if (this.noTitleWindow) {
@@ -45,41 +33,14 @@ define([
			this.inherited(arguments);
		},

		_mixEventsAndActions: function () {

			this.inherited(arguments);

			lang.mixin(this.actions, this.windowActions);
			delete this.windowActions;
		},

		_defineSubscriptions: function () {

			this.inherited(arguments);

			this.subscriptionsConfig.push({
				channel : this.getChannel("SHOW_WINDOW"),
				callback: "_subShowWindow",
				options: {
					predicate: lang.hitch(this, this._chkShowWindow)
				}
			});
		},

		_beforeShow: function(req) {

			var originalRet = this.inherited(arguments),
				dfdWindow = new Deferred();

			this._dfdWindow = dfdWindow;

			req && req.node && this._createWindow(req.node.domNode || req.node);

			if (originalRet && originalRet.resolve && !originalRet.isFulfilled()) {
				return all([originalRet, dfdWindow]);
			if (req && req.node) {
				var node = req.node.domNode || req.node;
				this._createWindow(node);
			}

			return dfdWindow;
			return this.inherited(arguments);
		},

		_createWindow: function(node) {
@@ -93,7 +54,7 @@ define([
			this._createWindowTitle();
			this._createWindowContent();

			this._loadWindowContent();
			this._emitEvt('LOADING');

			this._decorateTitleNode();
			this._decorateContentNode();
@@ -123,22 +84,6 @@ define([
			domStyle.set(this._windowContentNode, "height", "calc(100% - " + this.titleHeight + "px)");
		},

		_chkShowWindow: function(req) {

			return !!(this._dfdWindow && this._dfdWindow.resolve);
		},

		_subShowWindow: function(req) {

			this._loadedWindowContent();

			if (this._dfdWindow.isFulfilled()) {
				console.error("Deferred is already fulfilled at module '%s'", this.getChannel());
			} else {
				this._dfdWindow.resolve();
			}
		},

		_show: function(req) {

			if (req && req.node) {
@@ -152,18 +97,25 @@ define([

			var originalRet = this.inherited(arguments);

			if (originalRet && originalRet.resolve && !originalRet.isFulfilled()) {
				originalRet.then(lang.hitch(this, this._emitResize));
			if (originalRet && originalRet.then) {
				originalRet.then(lang.hitch(this, this._onWindowShown));
			} else {
				this._emitResize();
				this._onWindowShown();
			}

			return originalRet;
		},

		_onWindowShown: function() {

			this._emitEvt('LOADED');
			this._emitResize();
		},

		_decorateTitleNode: function() {

			var titleTextNode = put(this._windowTitleNode, "div.title", this.title || this.ownChannel);
			var titleTextValue = this.title || this.getOwnChannel(),
				titleTextNode = put(this._windowTitleNode, "div.title", titleTextValue);

			if (this.noButtonsWindow) {
				return;
@@ -255,49 +207,13 @@ define([

				// TODO esto debería ser responsabilidad de _Show, y emitirlo siempre cuando acabe
				// de hacer el _resize (quizá con un dfd de retorno??). Pensar
				if (this.node) {
					this._emitEvt('RESIZE', {
						width: this.node.offsetWidth,
						height: this.node.offsetHeight
					});
			}), 300);
		},

		// TODO estos métodos son copias de Loading. Cambiarlo para que se encargue Loading de hacerlo, o bien abstraerlo en
		// una zona común a ambos!!!!!
		_loadWindowContent: function() {

			var node = this._windowContentNode;

			this._loadingWindowContentNode = this._getLoadingElement(this.loadingClass);

			put(node, this._loadingWindowContentNode);
			put(node, "[" + this.loadingAttr + "=true]");

			domStyle.set(this._loadingWindowContentNode, "position", "relative");
		},

		// TODO estos métodos son copias de Loading. Cambiarlo para que se encargue Loading de hacerlo, o bien abstraerlo en
		// una zona común a ambos!!!!!
		_getLoadingElement: function(nodeClass) {

			var node = put("div." + nodeClass);
			node.innerHTML = LoadingTemplate();

			return node;
		},

		// TODO estos métodos son copias de Loading. Cambiarlo para que se encargue Loading de hacerlo, o bien abstraerlo en
		// una zona común a ambos!!!!!
		_loadedWindowContent: function() {

			if (!this._loadingWindowContentNode) {
				console.error("Loading node not found when tried to hide it, at module '%s'", this.getChannel());
				return;
				}

			put(this._windowContentNode, "[!" + this.loadingAttr + "]");
			put(this._loadingWindowContentNode, "!");
			this._loadingWindowContentNode = null;
			}), 300);
		},

		_hide: function(req) {