forked from DGNum/gestioCOF
move ModelList def
This commit is contained in:
parent
c9cce5b125
commit
d5dfd5fa93
1 changed files with 171 additions and 148 deletions
|
@ -288,154 +288,6 @@ class APIModelObject extends ModelObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple {@link Models.ModelObject} list.
|
|
||||||
* @memberof Models
|
|
||||||
*/
|
|
||||||
class ModelList {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Nested structure of the list
|
|
||||||
* @abstract
|
|
||||||
* @type {Models.ModelObject[]}
|
|
||||||
*/
|
|
||||||
static get models() { return []; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verbose names for list models
|
|
||||||
* @abstract
|
|
||||||
* @type {string[]}
|
|
||||||
*/
|
|
||||||
static get names() {
|
|
||||||
return this.models.map(function(v) {
|
|
||||||
return v.constructor.verbose_name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Templates used to render the different elements
|
|
||||||
* @abstract
|
|
||||||
* @type {string[]}
|
|
||||||
*/
|
|
||||||
static get templates() { return []; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates empty instance and populates it with data if given
|
|
||||||
* @param {Object[]} [datalist=[]]
|
|
||||||
*/
|
|
||||||
constructor(datalist) {
|
|
||||||
this.from(datalist || []);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches an object from the instance data, or creates it if
|
|
||||||
* it does not exist yet.<br>
|
|
||||||
* Parent objects are created recursively if needed.
|
|
||||||
* @param {number} depth depth on the nested structure of the list
|
|
||||||
* @param {Object} data
|
|
||||||
*/
|
|
||||||
get_or_create(depth, data) {
|
|
||||||
var model = this.constructor.models[depth];
|
|
||||||
var name = model.constructor.verbose_name ;
|
|
||||||
|
|
||||||
var existing = this.data[name].find(function (v){
|
|
||||||
return v.id === data['id'] ;
|
|
||||||
}) ;
|
|
||||||
|
|
||||||
if (existing) {
|
|
||||||
return existing;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (depth == this.constructor.models.length) {
|
|
||||||
var created = new model(data) ;
|
|
||||||
return created ;
|
|
||||||
} else {
|
|
||||||
var par_name = this.constructor.models[depth+1]
|
|
||||||
.constructor.verbose_name;
|
|
||||||
|
|
||||||
var par_data = data[par_name];
|
|
||||||
var created = new model(data);
|
|
||||||
var parnt = this.get_or_create(depth+1, par_data);
|
|
||||||
created[par_name] = parnt;
|
|
||||||
|
|
||||||
this.data[name].push(created);
|
|
||||||
return created ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets then populates the instance with the given data, starting from
|
|
||||||
* the lowest level Models.ModelObject in {@link Models.ModelList#models|models}.<br>
|
|
||||||
* @param {Object[]} datalist
|
|
||||||
*/
|
|
||||||
from(datalist) {
|
|
||||||
|
|
||||||
for (let key of this.constructor.names) {
|
|
||||||
this.data[key] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let data of datalist) {
|
|
||||||
this.get_or_create(data, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all Models.ModelObject from the list.
|
|
||||||
*/
|
|
||||||
clear() {
|
|
||||||
this.from([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders an element (and all its offspring) and appends it to the given container.
|
|
||||||
* Returns the completed container
|
|
||||||
* @param {jQuery} $container
|
|
||||||
* @param {Models.ModelObject} elt
|
|
||||||
* @param {Object} [options] Options for element render method
|
|
||||||
*/
|
|
||||||
render_element($container, elt, options) {
|
|
||||||
var depth = this.names.indexOf(elt.constructor.verbose_name);
|
|
||||||
|
|
||||||
if (depth == -1) {
|
|
||||||
return $();
|
|
||||||
} else if (depth == 0) {
|
|
||||||
$container.append(elt.display($(this.constructor.templates[0]), options));
|
|
||||||
return $container;
|
|
||||||
} else {
|
|
||||||
var name = this.constructor.names[depth];
|
|
||||||
var child_model = this.constructor.models[depth-1];
|
|
||||||
var children = this.data[child_model.verbose_name]
|
|
||||||
.filter(v => v[name].id == elt.id) ;
|
|
||||||
children.sort(child_model.compare);
|
|
||||||
|
|
||||||
$container.append(elt.display($(this.constructor.templates[depth]), options));
|
|
||||||
|
|
||||||
for (let child of children) {
|
|
||||||
this.render_element($container, child, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $container;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display stored data in container.
|
|
||||||
* @param {jQuery} $container
|
|
||||||
* @param {Object} [options] Options for element render method
|
|
||||||
*/
|
|
||||||
display($container, options) {
|
|
||||||
var root_model = this.constructor.models[this.constructor.models.length-1];
|
|
||||||
var roots = this.data[root_model.verbose_name];
|
|
||||||
roots.sort(root_model.compare);
|
|
||||||
|
|
||||||
for (let root of roots) {
|
|
||||||
this.render_element($container, root, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $container;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Account model. Can be accessed through API.
|
* Account model. Can be accessed through API.
|
||||||
* @extends Models.APIModelObject
|
* @extends Models.APIModelObject
|
||||||
|
@ -641,12 +493,27 @@ class ArticleCategory extends ModelObject {
|
||||||
return {'id': 0, 'name': ''};
|
return {'id': 0, 'name': ''};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbose name for ArticleCategory model.
|
||||||
|
* @default <tt>'article_category'</tt>
|
||||||
|
* @see {@link Models.ModelObject.verbose_name[ModelObject.verbose_name}
|
||||||
|
*/
|
||||||
|
static get verbose_name() { return 'article_category'; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @default {@link Formatters.ArticleCategoryFormatter}
|
* @default {@link Formatters.ArticleCategoryFormatter}
|
||||||
*/
|
*/
|
||||||
formatter() {
|
formatter() {
|
||||||
return ArticleCategoryFormatter;
|
return ArticleCategoryFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison function between ArticleCategory model instances.
|
||||||
|
* @see {@link Models.ModelObject.compare|ModelObject.compare}
|
||||||
|
*/
|
||||||
|
static compare(a, b) {
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -677,6 +544,13 @@ class Article extends ModelObject {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbose name for Article model
|
||||||
|
* @default <tt>'article'</tt>
|
||||||
|
* @see {@link Models.ModelObject.compare|ModelObject.compare}
|
||||||
|
*/
|
||||||
|
static get verbose_name() { return 'article'; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @default {@link Formatters.ArticleCategoryFormatter}
|
* @default {@link Formatters.ArticleCategoryFormatter}
|
||||||
*/
|
*/
|
||||||
|
@ -690,6 +564,155 @@ class Article extends ModelObject {
|
||||||
set price(v) { this._price = floatCheck(v); }
|
set price(v) { this._price = floatCheck(v); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple {@link Models.ModelObject} list.
|
||||||
|
* @memberof Models
|
||||||
|
*/
|
||||||
|
class ModelList {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nested structure of the list
|
||||||
|
* @abstract
|
||||||
|
* @type {Models.ModelObject[]}
|
||||||
|
*/
|
||||||
|
static get models() { return []; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbose names for list models
|
||||||
|
* @abstract
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
static get names() {
|
||||||
|
return this.models.map(function(v) {
|
||||||
|
return v.constructor.verbose_name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Templates used to render the different elements
|
||||||
|
* @abstract
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
static get templates() { return []; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates empty instance and populates it with data if given
|
||||||
|
* @param {Object[]} [datalist=[]]
|
||||||
|
*/
|
||||||
|
constructor(datalist) {
|
||||||
|
this.from(datalist || []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an object from the instance data, or creates it if
|
||||||
|
* it does not exist yet.<br>
|
||||||
|
* Parent objects are created recursively if needed.
|
||||||
|
* @param {number} depth depth on the nested structure of the list
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
get_or_create(depth, data) {
|
||||||
|
var model = this.constructor.models[depth];
|
||||||
|
var name = model.constructor.verbose_name ;
|
||||||
|
|
||||||
|
var existing = this.data[name].find(function (v){
|
||||||
|
return v.id === data['id'] ;
|
||||||
|
}) ;
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth == this.constructor.models.length) {
|
||||||
|
var created = new model(data) ;
|
||||||
|
return created ;
|
||||||
|
} else {
|
||||||
|
var par_name = this.constructor.models[depth+1]
|
||||||
|
.constructor.verbose_name;
|
||||||
|
|
||||||
|
var par_data = data[par_name];
|
||||||
|
var created = new model(data);
|
||||||
|
var parnt = this.get_or_create(depth+1, par_data);
|
||||||
|
created[par_name] = parnt;
|
||||||
|
|
||||||
|
this.data[name].push(created);
|
||||||
|
return created ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets then populates the instance with the given data, starting from
|
||||||
|
* the lowest level Models.ModelObject in {@link Models.ModelList#models|models}.<br>
|
||||||
|
* @param {Object[]} datalist
|
||||||
|
*/
|
||||||
|
from(datalist) {
|
||||||
|
|
||||||
|
for (let key of this.constructor.names) {
|
||||||
|
this.data[key] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let data of datalist) {
|
||||||
|
this.get_or_create(data, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all Models.ModelObject from the list.
|
||||||
|
*/
|
||||||
|
clear() {
|
||||||
|
this.from([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders an element (and all its offspring) and appends it to the given container.
|
||||||
|
* Returns the completed container
|
||||||
|
* @param {jQuery} $container
|
||||||
|
* @param {Models.ModelObject} elt
|
||||||
|
* @param {Object} [options] Options for element render method
|
||||||
|
*/
|
||||||
|
render_element($container, elt, options) {
|
||||||
|
var depth = this.names.indexOf(elt.constructor.verbose_name);
|
||||||
|
|
||||||
|
if (depth == -1) {
|
||||||
|
return $();
|
||||||
|
} else if (depth == 0) {
|
||||||
|
$container.append(elt.display($(this.constructor.templates[0]), options));
|
||||||
|
return $container;
|
||||||
|
} else {
|
||||||
|
var name = this.constructor.names[depth];
|
||||||
|
var child_model = this.constructor.models[depth-1];
|
||||||
|
var children = this.data[child_model.verbose_name]
|
||||||
|
.filter(v => v[name].id == elt.id) ;
|
||||||
|
children.sort(child_model.compare);
|
||||||
|
|
||||||
|
$container.append(elt.display($(this.constructor.templates[depth]), options));
|
||||||
|
|
||||||
|
for (let child of children) {
|
||||||
|
this.render_element($container, child, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display stored data in container.
|
||||||
|
* @param {jQuery} $container
|
||||||
|
* @param {Object} [options] Options for element render method
|
||||||
|
*/
|
||||||
|
display($container, options) {
|
||||||
|
var root_model = this.constructor.models[this.constructor.models.length-1];
|
||||||
|
var roots = this.data[root_model.verbose_name];
|
||||||
|
roots.sort(root_model.compare);
|
||||||
|
|
||||||
|
for (let root of roots) {
|
||||||
|
this.render_element($container, root, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- ---------- */
|
/* ---------- ---------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue