WIP: Aureplop/kpsul js refactor #501
1 changed files with 138 additions and 85 deletions
|
@ -1049,91 +1049,6 @@ class ModelForest {
|
|||
this.from({});
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a node (and all its offspring) and returns the
|
||||
* corresponding jQuery object.
|
||||
* @param {Models.TreeNode} node
|
||||
* @param {Object} templates Templates to render each model
|
||||
* @param {Object} [options] Options for element render method
|
||||
*/
|
||||
render_element(node, templates, options) {
|
||||
var modelname = node.constructor.verbose_name;
|
||||
var struct_data = this.constructor.structure[modelname];
|
||||
|
||||
var template = templates[modelname];
|
||||
var options = options || {} ;
|
||||
|
||||
var $container = $('<div></div>');
|
||||
$container.attr('id', modelname+'-'+node.id);
|
||||
|
||||
var $rendered = node.display($(template), options);
|
||||
$container.append($rendered);
|
||||
|
||||
var children = this.get_children(node);
|
||||
|
||||
if (children && children.length) {
|
||||
if (struct_data.child_sort)
|
||||
children.sort(struct_data.child_sort);
|
||||
else
|
||||
children.sort(children[0].constructor.compare);
|
||||
|
||||
for (let child of children) {
|
||||
var $child = this.render_element(child, templates, options);
|
||||
$container.append($child);
|
||||
}
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders node and adds it to given container.<br>
|
||||
* Assumes that the inserted node is the 'youngest'.
|
||||
* @param {jQuery} $container
|
||||
* @param {Models.TreeNode} node
|
||||
* @param {Object} templates Templates to render each model
|
||||
* @param {Object} [options] Options for element render method
|
||||
*/
|
||||
add_to_container($container, node, templates, options) {
|
||||
var struct = this.constructor.structure;
|
||||
var existing = this.get_parent(node) ;
|
||||
var first_missing = node;
|
||||
|
||||
while (existing && !($container.find('#'+existing.modelname+'-'+existing.id))) {
|
||||
first_missing = existing;
|
||||
existing = this.get_parent(existing);
|
||||
}
|
||||
|
||||
var $to_insert = this.render_element(first_missing, templates, options);
|
||||
if (existing) {
|
||||
$container.find('#'+existing.constructor.verbose_name+'-'+existing.id+'>:first-child')
|
||||
.after($to_insert);
|
||||
} else {
|
||||
$container.prepend($to_insert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display stored data in container.
|
||||
* @param {jQuery} $container
|
||||
* @param {Object} templates Templates to render each model
|
||||
* @param {Object} [options] Options for element render method
|
||||
*/
|
||||
display($container, templates, options) {
|
||||
if (this.is_empty())
|
||||
return;
|
||||
|
||||
if (this.constructor.root_sort)
|
||||
this.roots.sort(this.constructor.root_sort);
|
||||
else
|
||||
this.roots.sort(this.roots[0].constructor.compare);
|
||||
|
||||
for (let root of this.roots) {
|
||||
$container.append(this.render_element(root, templates, options));
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs for each node (in a DFS order) the callback function
|
||||
|
@ -1184,6 +1099,22 @@ class ModelForest {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
update(modelname, id, update_data) {
|
||||
var updated = null ;
|
||||
|
||||
function callback(node) {
|
||||
if (node.id == id) {
|
||||
node.update(update_data);
|
||||
updated = node ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
|
||||
this.traverse(modelname, callback);
|
||||
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1334,6 +1265,128 @@ class OperationList extends APIModelForest {
|
|||
}
|
||||
|
||||
|
||||
class ForestDisplay {
|
||||
|
||||
constructor($container, templates) {
|
||||
this._templates = templates ;
|
||||
this._$container = $container;
|
||||
this.data = new ModelForest();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders a node (and all its offspring) and returns the
|
||||
* corresponding jQuery object.
|
||||
* @param {Models.TreeNode} node
|
||||
* @param {Object} templates Templates to render each model
|
||||
* @param {Object} [options] Options for element render method
|
||||
*/
|
||||
render_element(node, options) {
|
||||
var modelname = node.constructor.verbose_name;
|
||||
var struct_data = this.data.constructor.structure[modelname];
|
||||
|
||||
var template = this._templates[modelname];
|
||||
var options = options || {} ;
|
||||
|
||||
var $container = $('<div></div>');
|
||||
$container.attr('id', modelname+'-'+node.id);
|
||||
|
||||
var $rendered = node.display($(template), options);
|
||||
$container.append($rendered);
|
||||
|
||||
var children = this.data.get_children(node);
|
||||
|
||||
if (children && children.length) {
|
||||
if (struct_data.child_sort)
|
||||
children.sort(struct_data.child_sort);
|
||||
else
|
||||
children.sort(children[0].constructor.compare);
|
||||
|
||||
for (let child of children) {
|
||||
var $child = this.render_element(child, options);
|
||||
$container.append($child);
|
||||
}
|
||||
}
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders node and adds it to the container.<br>
|
||||
* Assumes that the inserted node is the 'youngest'.
|
||||
* @param {Models.TreeNode} node
|
||||
* @param {Object} [options] Options for element render method
|
||||
*/
|
||||
add(node, options) {
|
||||
var struct = this.data.constructor.structure;
|
||||
var existing = this.data.get_parent(node) ;
|
||||
var first_missing = node;
|
||||
|
||||
while (existing && !(this._$container.find('#'+existing.modelname+'-'+existing.id))) {
|
||||
first_missing = existing;
|
||||
existing = this.data.get_parent(existing);
|
||||
}
|
||||
|
||||
var $to_insert = this.render_element(first_missing, options);
|
||||
//TODO better placement
|
||||
if (existing) {
|
||||
this._$container.find('#'+existing.constructor.verbose_name+'-'+existing.id+'>:first-child')
|
||||
.after($to_insert);
|
||||
} else {
|
||||
this._$container.prepend($to_insert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates stored data and displays it in container.
|
||||
* @param {Models.ModelForest} data
|
||||
* @param {Object} [options] Options for element render method
|
||||
*/
|
||||
render(data, options) {
|
||||
if (data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
var forest = this.data ;
|
||||
|
||||
if (forest.is_empty())
|
||||
return;
|
||||
|
||||
if (forest.constructor.root_sort)
|
||||
forest.roots.sort(forest.constructor.root_sort);
|
||||
else
|
||||
forest.roots.sort(forest.roots[0].constructor.compare);
|
||||
|
||||
for (let root of forest.roots) {
|
||||
this._$container.append(this.render_element(root, options));
|
||||
}
|
||||
|
||||
return this._$container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the display with same modelname and id as the given data.
|
||||
* @param {Object} data
|
||||
*/
|
||||
update(data) {
|
||||
var modelname = data.constructor.verbose_name ;
|
||||
var $new_elt = data.display($(this._templates[modelname]), {});
|
||||
|
||||
var $to_replace = this._$container.find('#'+modelname+'-'+data.id+'>:first-child');
|
||||
$to_replace.replaceWith($new_elt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all elements from container
|
||||
*/
|
||||
clear() {
|
||||
this._$container.html('');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------- ---------- */
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue