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

Integra Model en RestManager, refactoriza

Convierte la petición de parámetros de consulta en un proceso asíncrono,
para permitir la integración de Model como proveedor de estos valores
(siguiendo un JSON Schema y deserializando/serializando los valores de
consulta). Este es el primer paso para empezar a descartar el uso del
componente Filter.

Refactoriza ligeramente partes de la implementación de modelos y
parámetros de configuración.

Introduce el uso de estas novedades en el modo de citas de la vista de
distribución de especies.
parent aa2528f0
Loading
Loading
Loading
Loading
+59 −11
Original line number Diff line number Diff line
define([
	'dojo/_base/declare'
	, 'dojo/_base/lang'
	, 'dojo/Deferred'
	, 'src/component/model/ModelImpl'
	, 'src/redmicConfig'
], function(
	declare
	, lang
	, Deferred
	, ModelImpl
	, redmicConfig
) {

	return declare(null, {
@@ -12,11 +18,14 @@ define([

		// _requestParams: Object
		//   Contiene los parámetros recibidos para las URLs de consulta, indexados por channel y target.
		// _queryModelsByTarget: Object
		//   Contiene las instancias de los modelos con esquema de paŕametros de consulta, indexados por target.

		postMixInProperties: function() {

			const defaultConfig = {
				_requestParams: {}
				_requestParams: {},
				_queryModelsByTarget: {}
			};

			this._mergeOwnAttributes(defaultConfig);
@@ -27,7 +36,7 @@ define([
		_manageRequestParams: function(req, requesterChannel) {

			const target = req.target,
				reqParams = req.params || {},
				reqParams = req.params ?? {},
				sharedParams = reqParams.sharedParams;

			delete reqParams.sharedParams;
@@ -39,15 +48,13 @@ define([
			}

			if (sharedParams) {
				const sharedChannel = this._getSharedChannel(requesterChannel);

				const sharedAddedRequestParams = this._mixinRequestParams(target, reqParams, sharedChannel);
				const sharedChannel = this._getSharedChannel(requesterChannel),
					sharedAddedRequestParams = this._mixinRequestParams(target, reqParams, sharedChannel);

				return sharedAddedRequestParams;
			}

			const requesterAddedRequestParams = this._mixinRequestParams(target, reqParams, requesterChannel);

			return requesterAddedRequestParams;
		},

@@ -112,7 +119,48 @@ define([
			const sharedChannel = this._getSharedChannel(requesterChannel),
				sharedRequestQueryParams = this._getRequestParams(target, sharedChannel).query;

			return this._merge([sharedRequestQueryParams, requesterRequestQueryParams]);
			const mergedRequestQueryParams = this._merge([sharedRequestQueryParams, requesterRequestQueryParams]),
				queryDfd = new Deferred();

			if (!this._targetHasSchema(target)) {
				return queryDfd.resolve(mergedRequestQueryParams);
			}

			const modelInstance = this._getQueryModel(target, mergedRequestQueryParams);

			this._once(modelInstance.getChannel('SERIALIZED'), res => queryDfd.resolve(res.data));
			this._publish(modelInstance.getChannel('SERIALIZE'));

			return queryDfd;
		},

		_targetHasSchema: function(target) {

			return !!redmicConfig.schemas[target];
		},

		_getQueryModel: function(target, queryParams) {

			const modelInstance = this._queryModelsByTarget[target] ?? this._createQueryModel(target);

			this._publish(modelInstance.getChannel('DESERIALIZE'), {
				data: queryParams
			});

			return modelInstance;
		},

		_createQueryModel: function(target) {

			this.modelConfig = {
				parentChannel: this.getChannel(),
				target,
				props: {
					serializeAdditionalProperties: true
				}
			};

			return this._queryModelsByTarget[target] = new ModelImpl(this.modelConfig);
		}
	});
});
+42 −49
Original line number Diff line number Diff line
define([
	'dojo/_base/declare'
	, 'dojo/Deferred'
], function(
	declare
	, Deferred
) {

	return declare(null, {
@@ -33,9 +35,16 @@ define([
		_performGet: function(req, requesterChannel) {

			const url = this._getTargetForGet(req, requesterChannel),
				options = this._getOptionsForGet(req, requesterChannel);
				optionsDfd = this._getOptionsForGet(req, requesterChannel),
				getResponseDfd = new Deferred();

			return this._launchRequest(url, options);
			optionsDfd.then(options => {
				this._launchRequest(url, options).then(
					getResponse => getResponseDfd.resolve(getResponse),
					getError => getResponseDfd.reject(getError));
			});

			return getResponseDfd;
		},

		_getTargetForGet: function(req, requesterChannel) {
@@ -55,28 +64,38 @@ define([
		_getOptionsForGet: function(req, requesterChannel) {

			const method = 'GET',
				headers = this._merge([{}, this.headers, req.headers ?? {}]),
				query = this._getQueryDataWithQueryParamsReplaced(req.target, requesterChannel);
				headers = this._merge([{}, this.headers, req.headers ?? {}]);

			const options = {
				method,
				headers,
				query,
				sync: this.sync,
				preventCache: this.preventCache,
				timeout: this.timeout,
				handleAs: this.handleAs
			};

			return this._merge([options, req.options ?? {}]);
			const queryDfd = this._getQueryDataWithQueryParamsReplaced(req.target, requesterChannel),
				optionsDfd = new Deferred();

			queryDfd.then(query => optionsDfd.resolve(this._merge([options, {query}, req.options ?? {}])));

			return optionsDfd;
		},

		_performRequest: function(req, requesterChannel) {

			const url = this._getTargetForRequest(req, requesterChannel),
				options = this._getOptionsForRequest(req, requesterChannel);
				optionsDfd = this._getOptionsForRequest(req, requesterChannel),
				requestResponseDfd = new Deferred();

			return this._launchRequest(url, options);
			optionsDfd.then(options => {
				this._launchRequest(url, options).then(
					requestResponse => requestResponseDfd.resolve(requestResponse),
					requestError => requestResponseDfd.reject(requestError));
			});

			return requestResponseDfd;
		},

		_getTargetForRequest: function(req, requesterChannel) {
@@ -93,9 +112,8 @@ define([

		_getOptionsForRequest: function(req, requesterChannel) {

			const method = req.method ?? 'GET';

			const reqHeaders = this._getRequestRequestHeaders(req),
			const method = req.method ?? 'GET',
				reqHeaders = this._getRequestRequestHeaders(req),
				headers = this._merge([{}, this.headers, reqHeaders, req.headers ?? {}]);

			const options = {
@@ -107,16 +125,21 @@ define([
				handleAs: this.handleAs
			};

			const queryData = this._getQueryDataWithQueryParamsReplaced(req.target, requesterChannel);
			const queryDfd = this._getQueryDataWithQueryParamsReplaced(req.target, requesterChannel),
				optionsDfd = new Deferred();

			queryDfd.then(query => {
				if (method === 'POST') {
				options.data = JSON.stringify(queryData,
					options.data = JSON.stringify(query,
						(key, value) => this._filterQueryParamsForRequestBodyData(key, value));
				} else {
				options.query = queryData;
					options.query = query;
				}

			return this._merge([options, req.options ?? {}]);
				optionsDfd.resolve(this._merge([options, req.options ?? {}]));
			});

			return optionsDfd;
		},

		_filterQueryParamsForRequestBodyData: function(_key, value) {
@@ -168,36 +191,6 @@ define([
			}
		},

		_getRequestRequestQuery: function(req) {
			// TODO es posible que esta funcionalidad quepa mejor en _Store, antes de publicar, para que aquí se
			// reciban directamente los parámetros de consulta listos para usar.

			var sort = req.sort,
				query = {};

			if (sort) {
				var sortValue = '(';

				for (var i = 0; i < sort.length; i++) {
					var sortItem = sort[i],
						attributeName = sortItem.attribute,
						descendingDirection = sortItem.descending ?? false,
						directionPrefix = descendingDirection ? this.descendingPrefix : this.ascendingPrefix;

					if (i > 0) {
						sortValue += ',';
					}
					sortValue += encodeURIComponent(directionPrefix) + encodeURIComponent(attributeName);
				}

				sortValue += ')';

				query[this.sortParamName] = sortValue;
			}

			return query;
		},

		_performSave: function(req) {

			const url = this._getTargetForSave(req),
+3 −3
Original line number Diff line number Diff line
@@ -54,17 +54,17 @@ define([

		_targetIsMine: function(target) {

			var cleanTarget = this._cleanTrailingSlash(target);
			const cleanTarget = this._cleanTrailingSlash(target);

			if (target.length === cleanTarget.length) {
				target += '/';
			}

			if (this.target instanceof Array) {
				return this.target.indexOf(target) !== -1 || this.target.indexOf(cleanTarget) !== -1;
				return this.target.includes(target) || this.target.includes(cleanTarget);
			}

			return this.target === target || this.target === cleanTarget;
			return this.target && (this.target === target || this.target === cleanTarget);
		},

		_chkRequesterIsMe: function(res) {
+1 −1
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ define([
				parentChannel: this.getChannel(),
				target: this._getTarget(),
				noSerializeNullValue: false,
				filterSchema: true,
				idForGet: '_search/_schema',
				props: {
					serializeAdditionalProperties: true
				}
+31 −13
Original line number Diff line number Diff line
@@ -78,10 +78,6 @@ define([
			};

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

			if (this.filterSchema) {
				this.idForGet = '_search/_schema';
			}
		},

		_defineSubscriptions: function() {
@@ -191,9 +187,24 @@ define([

			this.inherited(arguments);

			// Si ya tengo el esquema, construyo el modelo
			if (this.schema) {
				this._buildModelWithSchema(this.schema);
			} else if (this.target.indexOf(redmicConfig.apiUrlVariable) !== -1 ||
				return;
			}

			// Si no tengo el esquema, pero existe una correspondencia con mi target, lo solicito
			const schemaTarget = this._getSchemaTarget();
			if (schemaTarget) {
				this._emitEvt('GET', {
					target: schemaTarget,
					requesterId: this.getOwnChannel()
				});
				return;
			}

			// TODO antiguo, eliminar! Si no tengo el esquema, le añado un sufijo conocido a mi target y lo solicito
			if (this.target.indexOf(redmicConfig.apiUrlVariable) !== -1 ||
				this.target.indexOf('undefined') !== -1) {

				this._emitEvt("GET", {
@@ -204,17 +215,24 @@ define([
			}
		},

		_itemAvailable: function(res, resWrapper) {
		_getSchemaTarget: function() {

			if (resWrapper.requesterId !== this.getOwnChannel()) {
				return;
			}
			return redmicConfig.schemas[this.target];
		},

			var schema = res.data;
		_targetIsMine: function(target) {

			if (this.filterSchema) {
				schema = schema?.schema;
			}
			return this.inherited(arguments) || this._schemaTargetIsMine(target);
		},

		_schemaTargetIsMine: function(target) {

			return this._getSchemaTarget() === target;
		},

		_itemAvailable: function(res, _resWrapper) {

			const schema = res.data?.schema;

			this._buildModelWithSchema(schema);
		},
Loading