diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index 0dbc03f2..d58bda1a 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -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.
- * 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}.
- * @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. * @extends Models.APIModelObject @@ -641,12 +493,27 @@ class ArticleCategory extends ModelObject { return {'id': 0, 'name': ''}; } + /** + * Verbose name for ArticleCategory model. + * @default 'article_category' + * @see {@link Models.ModelObject.verbose_name[ModelObject.verbose_name} + */ + static get verbose_name() { return 'article_category'; } + /** * @default {@link Formatters.ArticleCategoryFormatter} */ formatter() { 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 'article' + * @see {@link Models.ModelObject.compare|ModelObject.compare} + */ + static get verbose_name() { return 'article'; } + /** * @default {@link Formatters.ArticleCategoryFormatter} */ @@ -690,6 +564,155 @@ class Article extends ModelObject { 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.
+ * 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}.
+ * @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; + } +} + /* ---------- ---------- */ /**