Skip to content
This repository has been archived by the owner on Jun 27, 2018. It is now read-only.

Commit

Permalink
Merge pull request #1 from marmelab/update_enable_views
Browse files Browse the repository at this point in the history
[RFR] Update from reference refactoring & enabled views
  • Loading branch information
jeromemacias committed May 20, 2015
2 parents cdaf1ae + ac3491b commit 898ec19
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 55 deletions.
3 changes: 2 additions & 1 deletion lib/Application.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ class Application {
this._menu = this.buildMenuFromEntities();
}
return this._menu
};
}

this._menu = menu;
return this;
}
Expand Down
161 changes: 120 additions & 41 deletions lib/Queries/ReadQueries.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class ReadQueries extends Queries {
page = page || 1;
let url = view.getUrl();

return this.getRawValues(view.entity, view.name(), view.type, page, view.perPage(), filters, view.filters(), sortField || view.getSortFieldName(), sortDir || view.sortDir(), url)
sortField = sortField || view.getSortFieldName();
sortDir = sortDir || view.sortDir();

return this.getRawValues(view.entity, view.name(), view.type, page, view.perPage(), filters, view.filters(), sortField, sortDir, url)
.then((values) => {
return {
data: values.data,
Expand Down Expand Up @@ -63,16 +66,19 @@ class ReadQueries extends Queries {
getRawValues(entity, viewName, viewType, page, perPage, filterValues, filterFields, sortField, sortDir, url) {
let params = {};

// Compute pagination
if (page !== -1) {
params._page = (typeof (page) === 'undefined') ? 1 : parseInt(page, 10);
params._perPage = perPage;
}

// Compute sorting
if (sortField && sortField.split('.')[0] === viewName) {
params._sortField = sortField.split('.')[1];
params._sortDir = sortDir;
}

// Compute filtering
if (filterValues && Object.keys(filterValues).length !== 0) {
params._filters = {};
let filterName;
Expand All @@ -96,75 +102,148 @@ class ReadQueries extends Queries {

/**
* Returns all References for an entity with associated values [{targetEntity.identifier: targetLabel}, ...]
* by calling the API for each entries
*
* @param {Object} references A hash of Reference and ReferenceMany objects
* @param {ReferenceField} references A hash of Reference and ReferenceMany objects
* @param {Array} rawValues
*
* @returns {promise}
* @returns {Promise}
*/
getReferencedData(references, rawValues) {
let getRawValues = this.getRawValues.bind(this),
getOne = this.getOne.bind(this),
identifiers,
calls = [],
data;
getFilteredReferenceData(references, rawValues) {
if (!references || !Object.keys(references).length) {
return this._promisesResolver.empty({});
}

let getOne = this.getOne.bind(this),
calls = [];

for (let i in references) {
let reference = references[i],
targetEntity = reference.targetEntity();

if (!rawValues) {
calls.push(getRawValues(targetEntity, targetEntity.name() + '_ListView', 'listView', 1, reference.perPage(), reference.filters(), {}, reference.sortField(), reference.sortDir()));
targetEntity = reference.targetEntity(),
identifiers = reference.getIdentifierValues(rawValues);

continue;
for (let k in identifiers) {
calls.push(getOne(targetEntity, 'listView', identifiers[k], reference.name()));
}
}

// get only for identifiers
identifiers = reference.getIdentifierValues(rawValues);
return this.fillFilteredReferencedData(calls, references, rawValues);
};

/**
* Returns all References for an entity with associated values [{targetEntity.identifier: targetLabel}, ...]
* by calling the API once
*
* @param {[ReferenceField]} references A hash of Reference and ReferenceMany objects
* @param {Array} rawValues
*
* @returns {Promise}
*/
getOptimizedReferencedData(references, rawValues) {
if (!references || !Object.keys(references).length) {
return this._promisesResolver.empty({});
}

let getRawValues = this.getRawValues.bind(this),
calls = [];

for (let i in references) {
let reference = references[i],
targetEntity = reference.targetEntity(),
identifiers = reference.getIdentifierValues(rawValues);

// Check if we should retrieve values with 1 or multiple requests
if (reference.hasSingleApiCall()) {
let singleCallFilters = reference.getSingleApiCall(identifiers);
calls.push(getRawValues(targetEntity, targetEntity.name() + '_ListView', 'listView', 1, reference.perPage(), singleCallFilters, {}, reference.sortField(), reference.sortDir()));
let singleCallFilters = reference.getSingleApiCall(identifiers);
calls.push(getRawValues(targetEntity, targetEntity.name() + '_ListView', 'listView', 1, reference.perPage(), singleCallFilters, {}, reference.sortField(), reference.sortDir()));
}

continue;
}
return this.fillOptimizedReferencedData(calls, references);
}

for (let k in identifiers) {
calls.push(getOne(targetEntity, 'listView', identifiers[k], reference.name()));
}
/**
* Returns all References for an entity with associated values [{targetEntity.identifier: targetLabel}, ...]
* without filters on an entity
*
* @param {[ReferenceField]} references A hash of Reference and ReferenceMany objects
*
* @returns {Promise}
*/
getAllReferencedData(references) {
if (!references || !Object.keys(references).length) {
return this._promisesResolver.empty({});
}

// Fill all reference entries
return this._promisesResolver.allEvenFailed(calls)
let calls = [],
getRawValues = this.getRawValues.bind(this);

for (let i in references) {
let reference = references[i],
targetEntity = reference.targetEntity();

calls.push(getRawValues(targetEntity, targetEntity.name() + '_ListView', 'listView', 1, reference.perPage(), reference.filters(), {}, reference.sortField(), reference.sortDir()));
}

return this.fillOptimizedReferencedData(calls, references);
}

/**
* Fill all reference entries to return [{targetEntity.identifier: targetLabel}, ...]
*
* @param {[Promise]} apiCalls
* @param {[Reference]} references
* @returns {Promise}
*/
fillOptimizedReferencedData(apiCalls, references) {
return this._promisesResolver.allEvenFailed(apiCalls)
.then((responses) => {
if (responses.length === 0) {
return {};
}

let referencedData = {},
response,
i = 0;

for (let j in references) {
let reference = references[j],
singleCallFilters = reference.getSingleApiCall(identifiers);

// Retrieve entries depending on 1 or many request was done
if (singleCallFilters || !rawValues) {
response = responses[i++];
if (response.status == 'error') {
// the response failed
continue;
}

referencedData[reference.name()] = response.result.data;

// Retrieve entries depending on 1 or many request was done
if (response.status == 'error') {
// the response failed
continue;
}

data = [];
identifiers = reference.getIdentifierValues(rawValues);
referencedData[reference.name()] = response.result.data;
}

return referencedData;
});
}

/**
* Fill all reference entries to return [{targetEntity.identifier: targetLabel}, ...]
*
* @param {[Promise]} apiCalls
* @param {[Reference]} references
* @param {[Object]} rawValues
* @returns {Promise}
*/
fillFilteredReferencedData(apiCalls, references, rawValues) {
return this._promisesResolver.allEvenFailed(apiCalls)
.then((responses) => {
if (responses.length === 0) {
return {};
}

let referencedData = {},
response,
i = 0;

for (let j in references) {
let data = [],
reference = references[j],
identifiers = reference.getIdentifierValues(rawValues);

for (let k in identifiers) {
response = responses[i++];
if (response.status == 'error') {
Expand All @@ -183,7 +262,7 @@ class ReadQueries extends Queries {

return referencedData;
});
};
}

/**
* Returns all ReferencedList for an entity for associated values [{targetEntity.identifier: [targetFields, ...]}}
Expand Down Expand Up @@ -217,7 +296,7 @@ class ReadQueries extends Queries {
for (let i in referencedLists) {
let response = responses[j++];
if (response.status == 'error') {
// one of the responses failed
// If a response fail, skip it
continue;
}

Expand Down
6 changes: 6 additions & 0 deletions lib/Utils/PromisesResolver.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@

class PromisesResolver {
static empty(value) {
return new Promise((resolve) => {
resolve(value);
});
}

static allEvenFailed(promises) {
if (!Array.isArray(promises)) {
throw Error('allEvenFailed can only handle an array of promises');
Expand Down
1 change: 1 addition & 0 deletions lib/View/DeleteView.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class DeleteView extends View {
constructor(name) {
super(name);
this._type = 'DeleteView';
this._enabled = true;
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/View/MenuView.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ class MenuView extends View {
this._icon = null;
}

get enabled() {
return this._enabled || this.entity.views['ListView'].enabled;
}

icon() {
if (arguments.length) {
console.warn('entity.menuView() is deprecated. Please use the Menu class instead');
Expand Down
39 changes: 36 additions & 3 deletions lib/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class View {
this._description = '';
this._template = null;

this._enabled = true;
this._enabled = false;
this._fields = [];
this._type = null;
this._name = name;
Expand All @@ -18,7 +18,7 @@ class View {
}

get enabled() {
return this._enabled;
return this._enabled || !!this._fields.length;
}

title(title) {
Expand Down Expand Up @@ -47,17 +47,21 @@ class View {

disable() {
this._enabled = false;

return this;
}

enable() {
this._enabled = true;

return this;
}

/**
* @deprecated Use getter "enabled" instead
*/
isEnabled() {
return this._enabled;
return this.enabled;
}

/**
Expand Down Expand Up @@ -136,6 +140,14 @@ class View {
return result;
}

getNonOptimizedReferences() {
return this._getReferencesByOptimizationType(false);
}

getOptimizedReferences() {
return this._getReferencesByOptimizationType(true);
}

getReferencedLists() {
let result = {};
let lists = this._fields.filter(f => f.type() === 'referenced_list');
Expand Down Expand Up @@ -231,6 +243,27 @@ class View {
}
});
}

/**
*
* @param {Boolean} optimized
* @returns {[Reference]}
* @private
*/
_getReferencesByOptimizationType(optimized=true) {
let result = {},
references = this.getReferences();

for (let i in references) {
let reference = references[i];

if (!!reference.getSingleApiCall() === optimized) {
result[i] = reference;
}
}

return result;
}
}

export default View;
Loading

0 comments on commit 898ec19

Please sign in to comment.