Skip to content

Commit

Permalink
Merge branch 'feature/location-field'
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-cz committed Mar 7, 2016
2 parents ff1b6f2 + af5c194 commit b7a2974
Show file tree
Hide file tree
Showing 4 changed files with 336 additions and 107 deletions.
232 changes: 138 additions & 94 deletions assets/js/Processor.factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

'use strict';

App.module.factory('Processor', ['$http', function ProcessorFactory($http) {
App.module.factory('Processor', ['$q', '$http', '$timeout', function ProcessorFactory($q, $http, $timeout) {

Processor.$q = $q;
Processor.$http = $http;
Processor.$timeout = $timeout;

return Processor;

Expand Down Expand Up @@ -97,133 +99,175 @@
};

/**
* Convert row data to entry
* Proccess given row
* [async]
*
* @protected
* @param {Object} dataRow
* @param {Function} callback
* @return {Object}
* @return {Processor}
*/
Processor.prototype.getEntryData = function(dataRow, callback) {
Processor.prototype.processRow = function(dataRow) {

// Static data
/** @type {Object} Entry data */
var entry = {};
/** @type {Array} promises stack */
var promises = [];

var processedSlugs = 0;
var totalSlugs = this.dataMapper.filter(function(dataMapperRow) {
return (dataMapperRow.field.slug && dataMapperRow.slugColumn !== undefined);
}).length;
// Loop trough mapper fields
this.dataMapper.forEach(function(mapperRow, i) {

// Fields
this.dataMapper.forEach(function(dataMapperRow) {
// Merge in data collected synchronously
this.decorateEntry(entry, promises, dataRow, mapperRow);
}, this);

// Get data from row and add filter
if (dataMapperRow.column !== undefined) {
// Save
Processor.$q.all(promises)

dataMapperRow.input = dataRow[dataMapperRow.column];
.then(angular.bind(this, function(entryDataRows) {

if (dataMapperRow.filter) {
dataMapperRow.output = dataMapperRow.filter(dataMapperRow.input, dataMapperRow.field);
} else {
dataMapperRow.output = dataMapperRow.input;
}
// Prepend data collected synchronously
entryDataRows.unshift({});
entryDataRows.unshift(entry);

entry[dataMapperRow.field.name] = dataMapperRow.output;
}
// Append data collected asynchronously
var entryData = angular.extend.apply(undefined, entryDataRows);

Processor.$http.post(
App.route('/api/collections/saveentry'),
{
collection: {
_id: this.collectionId
},
entry : entryData
}
/*
// Test
App.route('/api/collections/findOne'),
{
filter: {
_id: this.collectionId
}
},
{
responseType: 'json'
}
/**/
)
.success(angular.bind(this, function(data, status, headers, config) {
this.finishedProcessingEntry(dataRow);
}))

.error(angular.bind(function(data, status, headers, config) {
this.finishedProcessingEntry(dataRow, data);
}))
;

return entryData;
}))
// Promise should not have any catches
.catch(angular.bind(this, function(error) {

error = (error || 'Unknown error');

this.finishedProcessingEntry(
dataRow,
App.i18n.get('import.notify.Import field error', error)
);
}));

return this;
};

/**
* Process entry cell
* [async]
*
* @param {Object} entry
* @param {Array} promises - Promises stack for async results
* @param {Array} dataRow
* @param {Object} mapperRow
*
* @return {Object} entry
*/
Processor.prototype.decorateEntry = function(entryData, promises, dataRow, mapperRow) {

// Add in locales
if (dataMapperRow.field.localize && dataMapperRow.localizations.length) {
var deferred;

dataMapperRow.localizations.forEach(function(localization) {
// Filter
if (mapperRow.column !== undefined) {

if (localization.column) {
mapperRow.input = dataRow[mapperRow.column];

// Copy over data into localization
localization.output = dataRow[localization.column];
// Filter
if (!mapperRow.filter) {
mapperRow.output = mapperRow.input;
// Stateless filter
} else if (!mapperRow.filter.$stateful) {
mapperRow.output = mapperRow.filter(mapperRow.input, mapperRow.field);
// Stateful filter
} else {
deferred = Processor.$q.defer();

// Store in entry
entry[dataMapperRow.field.name + '_' + localization.code] = localization.output;
}
});
}
mapperRow.output = mapperRow.filter(mapperRow.input, mapperRow.field, {deferred: deferred});

// Process slug
if (dataMapperRow.field.slug && dataMapperRow.slugColumn !== undefined) {
// Add async output from filter
promises.push(
deferred.promise.then(function(filterOutput) {

// Save in input
dataMapperRow.slugInput = dataRow[dataMapperRow.slugColumn];
entryData[mapperRow.field.name] = filterOutput;

// note: Using setTimeout because of instant DOM update-read is involved.
// see: http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful
window.setTimeout(function() {
entry[dataMapperRow.field.name + '_slug'] = dataMapperRow.slugOutput;
return entryData;
})
);

// If this is last async function, invoke callback.
if (++processedSlugs >= totalSlugs) {
callback.call(this, entry);
}
}.bind(this), 10);
// Add delay
if (mapperRow.filter.delay) {
promises.push(Processor.$timeout(function() {}, mapperRow.filter.delay));
}
}

}, this);

// When there are no async functions, invoke callback.
if (!totalSlugs) {
callback.call(this, entry);
// Set data so it's svailable for following processing
entryData[mapperRow.field.name] = mapperRow.output;
}

return entry;
};
// Add in locales
if (mapperRow.field.localize && mapperRow.localizations.length) {

/**
* Proccess given row
* [async]
*
* @protected
* @param {Object} dataRow
* @return {Processor}
*/
Processor.prototype.processRow = function(dataRow) {
mapperRow.localizations.forEach(function(localization) {

// V1 (using async data)
this.getEntryData(dataRow, function(entryData) {
if (localization.column) {

Processor.$http.post(
App.route('/api/collections/saveentry'),
{
collection: {
_id: this.collectionId
},
entry : entryData
}
/**
// Test
App.route('/api/collections/findOne'),
{
filter: {
_id: this.collectionId
}
},
{
responseType: 'json'
// Copy over data into localization
localization.output = dataRow[localization.column];

// Store in entry
entryData[mapperRow.field.name + '_' + localization.code] = localization.output;
}
*/
)
.success(function(data, status, headers, config) {
this.finishedProcessingEntry(dataRow);
}.bind(this))
});
}

.error(function(data, status, headers, config) {
this.finishedProcessingEntry(dataRow, data);
}.bind(this))
;
});
// Process slug
if (mapperRow.field.slug && mapperRow.slugColumn !== undefined) {

return this;
// Save in input
mapperRow.slugInput = dataRow[mapperRow.slugColumn];

promises.push(
Processor.$timeout(function() {

entryData[mapperRow.field.name + '_slug'] = mapperRow.slugOutput;

return entryData;
}, 10)
);
}

return entryData;
};

/**
* Finalize tasks after entry has (not) been cerated.
* When one task is finished, another is started
*
* @protected
* @param {Object} dataRow
Expand All @@ -242,7 +286,7 @@

// Mark failure
if (errorDetails && typeof this.callbacks.onError == 'function') {
this.callbacks.onError(dataRow, erorDetails);
this.callbacks.onError(dataRow, errorDetails, rowIndex);
}

if (typeof this.callbacks.onProgress == 'function') {
Expand Down
Loading

0 comments on commit b7a2974

Please sign in to comment.