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

Revisa manejo de rutas y de acciones de components

Remodela el tratamiento de rutas en el componente Router, evitando la
acumulación de rutas repetidas en el historial y recordando la última
ruta válida cuando se hace login, retornando a la misma si el usuario
se identificó con éxito.

Router ahora escucha desde componente App cuándo se ha cambiado de vista
con éxito para recordar la ruta, siempre que no sea ni login ni home.

Aplica limpieza de parámetros de url sólo si se han podido capturar, en
caso de no existir no la reemplaza.

En base de componentes, implementa la posibilidad de construir canales
con el método _buildChannel usando como segundo argumento una propiedad
de acción, en lugar de requerir su valor directamente. Se refactoriza
para simplificar el manejo de acciones y se aprovecha para mejorar la
comprobación de validez de las mismas.
parent 275bdd3c
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -103,10 +103,12 @@ define([
				events: {
					GET_CREDENTIALS: 'getCredentials',
					GET_MODULE: 'getModule',
					CLEAR_MODULE: 'clearModule'
					CLEAR_MODULE: 'clearModule',
					MODULE_CHANGED: 'moduleChanged'
				},
				actions: {
					CHANGE_MODULE: 'changeModule'
					CHANGE_MODULE: 'changeModule',
					MODULE_CHANGED: 'moduleChanged'
				},

				_reconnectTimeout: 10000,
@@ -196,6 +198,9 @@ define([
			},{
				event: 'CLEAR_MODULE',
				channel: this._moduleStore.getChannel('CLEAR_MODULE')
			},{
				event: 'MODULE_CHANGED',
				channel: this.getChannel('MODULE_CHANGED')
			});
		},

@@ -233,12 +238,18 @@ define([
				locationQuery = req.locationQuery,
				routeChanged = this._changeModule(route);

			if (routeChanged) {
			if (!routeChanged) {
				return;
			}

			this._emitEvt('TRACK', {
				type: TRACK.type.page,
				info: route + locationQuery
			});
			}

			this._emitEvt('MODULE_CHANGED', {
				route: route
			});
		},

		_showReconnectingMessage: function() {
+56 −14
Original line number Diff line number Diff line
@@ -29,10 +29,12 @@ define([
			this.config = {
				ownChannel: 'router',
				events: {
					GET_QUERY_PARAMS: 'getQueryParams'
					GET_QUERY_PARAMS: 'getQueryParams',
					CHANGE_MODULE: 'changeModule'
				},
				actions: {
					CHANGE_MODULE: 'changeModule',
					MODULE_CHANGED: 'moduleChanged',
					EVALUATE_ROUTE: 'evaluateRoot',
					GO_TO_ROOT_ROUTE: 'goToRootRoute',
					GO_TO_ERROR_ROUTE: 'goToErrorRoute',
@@ -70,6 +72,12 @@ define([
			},{
				channel : this.getChannel('GET_QUERY_PARAMS'),
				callback: '_subGetQueryParams'
			},{
				channel : this._buildChannel(this.rootChannel, 'MODULE_CHANGED'),
				callback: '_subModuleChanged',
				options: {
					predicate: lang.hitch(this, this._chkModuleChanged)
				}
			});
		},

@@ -78,6 +86,9 @@ define([
			this.publicationsConfig.push({
				event: 'GET_QUERY_PARAMS',
				channel: this.getChannel('GOT_QUERY_PARAMS')
			},{
				event: 'CHANGE_MODULE',
				channel: this._buildChannel(this.rootChannel, 'CHANGE_MODULE')
			});
		},

@@ -121,10 +132,15 @@ define([
				return;
			}

			var url = target.pathname + target.search + target.hash;
			var locationObj = globalThis.location,
				currentPath = locationObj.pathname,
				nextPath = target.pathname;

			this._addHistory(url);
			if (nextPath !== currentPath) {
				var nextUrl = target.pathname + target.search + target.hash;
				this._addHistory(nextUrl);
				this._onRouteChange();
			}

			evt.preventDefault();
		},
@@ -134,24 +150,34 @@ define([
			globalThis.history.pushState(null, null, value);
		},

		_replaceHistory: function(value) {

			globalThis.history.replaceState(null, null, value);
		},

		_onRouteChange: function() {

			var locationObj = globalThis.location,
				locationPath = locationObj.pathname,
				route = locationPath.substr(1),
				routeIsEmpty = !route || route === '' || route === this.paths.ROOT,
				loginWasSuccessful = route === this.paths.LOGIN && this._userFound;
				route = locationPath.slice(1);

			if (routeIsEmpty || loginWasSuccessful) {
			var routeIsEmpty = !route || route === '' || route === this.paths.ROOT;
			if (routeIsEmpty) {
				route = this.paths.HOME;
				this._addHistory(route);
				this._replaceHistory(route);
			}

			var locationQuery = locationObj.search;
			if (route === this.paths.LOGIN && this._userFound) {
				var prevRouteExistsAndIsNotHome = this._prevRoute && this._prevRoute !== this.paths.HOME;

				route = prevRouteExistsAndIsNotHome ? this._prevRoute : this.paths.HOME;
				this._replaceHistory(route);
			}

			this._handleQueryParameters(locationQuery.substr(1));
			var locationQuery = locationObj.search;
			this._handleQueryParameters(locationQuery.slice(1));

			this._publish(this.getParentChannel('CHANGE_MODULE'), {
			this._emitEvt('CHANGE_MODULE', {
				route: route,
				locationQuery: locationQuery
			});
@@ -195,6 +221,20 @@ define([
			});
		},

		_chkModuleChanged: function(res) {

			var route = res.route;

			return route !== this.paths.HOME && route !== this.paths.LOGIN && this._prevRoute !== route;
		},

		_subModuleChanged: function(res) {

			var route = res.route;

			this._prevRoute = route;
		},

		_goToRootPage: function() {

			globalThis.location.href = this.paths.ROOT;
@@ -209,7 +249,9 @@ define([

			this._currentQueryParams = this._getQueryParameters(queryString);

			if (Object.keys(this._currentQueryParams).length) {
				this._removeQueryParametersFromHref();
			}
		},

		_getQueryParameters: function(queryString) {
@@ -222,7 +264,7 @@ define([
			var locationObj = globalThis.location,
				href = locationObj.origin + locationObj.pathname + locationObj.hash;

			globalThis.history.replaceState(null, null, href);
			this._replaceHistory(href);
		}
	});
});
+66 −33
Original line number Diff line number Diff line
@@ -235,6 +235,8 @@ define([
			this._mixModuleEventsAndActions();
			this._mixEventsAndActions();

			this._actionsPropNames = Object.keys(this.actions);

			if (this.getOwnChannel() !== this.rootChannel && !this.parentChannel) {
				console.error("The module '%s' does not have a parent", this.getChannel());
			}
@@ -349,7 +351,7 @@ define([
				alwaysOn: true
			},{
				event: 'TRACK',
				channel: this._buildChannel(this.analyticsChannel, this.actions.TRACK),
				channel: this._buildChannel(this.analyticsChannel, 'TRACK'),
				alwaysOn: true
			},{
				event: 'DESTROY',
@@ -375,39 +377,67 @@ define([
			return this.ownChannel;
		},

		_getActionValue: function(/*String*/ actionPropName) {

			return this.actions[actionPropName];
		},

		checkAction: function(/*String*/ action) {

			return !(action && (action === action.toUpperCase() && isNaN(parseInt(action, 10))) &&
				!this.actions[action]);
			if (action === undefined || action === null || action === '') {
				return false;
			}

			var actionIsUpperCase = action === action.toUpperCase();

			if (actionIsUpperCase) {
				var actionIsPropName = this._getActionValue(action) !== undefined;
				return actionIsPropName;
			}

			var actionPropName = this._getActionPropName(action);

			return actionPropName && !!actionPropName.length;
		},

		getChannel: function(/*String?*/ action) {
		_getActionPropName: function(/*String*/ actionValue) {

			var channel = this.getParentChannel(this.ownChannel);
			var actionPropNameFound = this._actionsPropNames.filter(
				lang.hitch(this, function(actionValueToCheck, actionPropName) {

			this._checkActionExistence(action);
				return this.actions[actionPropName] === actionValueToCheck;
			}, actionValue));

			if (!action) {
				return this._buildChannel(channel);
			return actionPropNameFound.length && actionPropNameFound[0];
		},

		getChannel: function(/*String?*/ action) {

			var channel = this._buildChannel(this.getParentChannel(), this.getOwnChannel());

			if (action === undefined || action === null) {
				return channel || '';
			}

			return this._buildChannel(channel, this.actions[action] || action);
			this._checkActionExistence(action);

			return this._buildChannel(channel, action);
		},

		getParentChannel: function(/*String?*/ action) {

			var channel = this.parentChannel;

			this._checkActionExistence(action);

			if (!action) {
				return this._buildChannel(channel);
			if (action === undefined || action === null) {
				return channel || '';
			}

			return this._buildChannel(channel, this.actions[action] || action);
			this._checkActionExistence(action);

			return this._buildChannel(channel, action);
		},

		_checkActionExistence: function(/*String?*/ action) {
		_checkActionExistence: function(/*String*/ action) {

			if (!this.checkAction(action)) {
				console.error("The action '%s' does not exist at module '%s'", action,
@@ -415,22 +445,25 @@ define([
			}
		},

		_buildChannel: function(/*String*/ channel, /*String?*/ action) {
		_buildChannel: function(/*String*/ channel, /*String?*/ channelSuffix) {

			var channelBuilt = channel || "";

			if (arguments.length > 1 && !action) {
				console.error("Tried to build a channel '%s' with invalid action at module '%s'", channel,
			if (arguments.length > 1 && !channelSuffix) {
				console.error("Tried to build a channel '%s' with invalid suffix at module '%s'", channel,
					this.parentChannel + this.channelSeparator + this.ownChannel);

				return channelBuilt;
			}

			if (action) {
			if (channelSuffix) {
				var actionValue = this.actions && this._getActionValue(channelSuffix),
					suffixValue = actionValue || channelSuffix;

				if (channelBuilt.length) {
					channelBuilt += this.channelSeparator;
				}
				channelBuilt += action;
				channelBuilt += suffixValue;
			}

			return channelBuilt;
@@ -660,8 +693,8 @@ define([

		_connectAction: function(actionToReconnect) {

			var action = this.actions[actionToReconnect];
			delete this.actionsPaused[action];
			var actionValue = this._getActionValue(actionToReconnect);
			delete this.actionsPaused[actionValue];
		},

		_getPaused: function() {
@@ -708,8 +741,8 @@ define([

		_disconnectAction: function(actionToDisconnect) {

			var action = this.actions[actionToDisconnect];
			this.actionsPaused[action] = true;
			var actionValue = this._getActionValue(actionToDisconnect);
			this.actionsPaused[actionValue] = true;
		},

		_pause: function() {
@@ -719,7 +752,9 @@ define([

		_disconnectModule: function() {

			var actionOnChildrenDfdsName = '_' + this.actions.DISCONNECTED + this._childrenActionDfdsNameSuffix;
			var actionOnChildrenDfdsName = '_' + this._getActionValue('DISCONNECTED') +
				this._childrenActionDfdsNameSuffix;

			delete this[actionOnChildrenDfdsName];

			this._pause();
@@ -818,7 +853,7 @@ define([
				childModuleOwnChannel = this._getActionFromChannel(childModuleChannel);

			this._childrenModules[childModuleOwnChannel] = false;
			this._resolvePendingChildrenActionDfds(childModuleChannel, this.actions.DISCONNECTED);
			this._resolvePendingChildrenActionDfds(childModuleChannel, this._getActionValue('DISCONNECTED'));
		},

		_onChildDestroyed: function(res) {
@@ -827,7 +862,7 @@ define([
				childModuleOwnChannel = this._getActionFromChannel(childModuleChannel);

			delete this._childrenModules[childModuleOwnChannel];
			this._resolvePendingChildrenActionDfds(childModuleChannel, this.actions.DESTROYED);
			this._resolvePendingChildrenActionDfds(childModuleChannel, this._getActionValue('DESTROYED'));
		},

		_resolvePendingChildrenActionDfds: function(childModuleChannel, action) {
@@ -1136,10 +1171,10 @@ define([

		_prepareModuleActionAfterChildrenActionsAreDone: function(args) {

			var action = this.actions[args.action],
			var actionValue = this._getActionValue(args.action);
				cbk = args.cbk,
				waitForDisconnected = args.waitForDisconnected || false,
				actionOnChildrenDfdsName = '_' + action + this._childrenActionDfdsNameSuffix,
				actionOnChildrenDfdsName = '_' + actionValue + this._childrenActionDfdsNameSuffix,
				currentModuleChannel = this.getChannel();

			this[actionOnChildrenDfdsName] = {};
@@ -1160,11 +1195,9 @@ define([

		_propagateActionToChildren: function(action, req) {

			var actionValue = this.actions[action];

			for (var childOwnChannel in this._childrenModules) {
				var childChannel = this._buildChannel(this.getChannel(), childOwnChannel),
					childActionChannel = this._buildChannel(childChannel, actionValue);
					childActionChannel = this._buildChannel(childChannel, action);

				this._publish(childActionChannel, req);
			}
@@ -1173,7 +1206,7 @@ define([
		_destroyModule: function() {

			var currentModuleChannel = this.getChannel(),
				actionOnChildrenDfdsName = '_' + this.actions.DESTROYED + this._childrenActionDfdsNameSuffix;
				actionOnChildrenDfdsName = '_' + this._getActionValue('DESTROYED') + this._childrenActionDfdsNameSuffix;

			delete this[actionOnChildrenDfdsName];