From a05a075962e6bf11439ef059d7a601ada0d9f94b Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Wed, 8 Mar 2017 10:47:51 -0300 Subject: [PATCH] apimodellist & articlelist --- kfet/static/kfet/js/kfet.api.js | 125 ++++++++++++++++++++++++++------ 1 file changed, 104 insertions(+), 21 deletions(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index d58bda1a..9beefbb6 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -251,7 +251,7 @@ class APIModelObject extends ModelObject { $.getJSON(this.url_object, api_options) .done(function (json, textStatus, jqXHR) { - that.from(json) + that.from(json); on_success(json, textStatus, jqXHR); }) .fail(on_error); @@ -498,7 +498,7 @@ class ArticleCategory extends ModelObject { * @default 'article_category' * @see {@link Models.ModelObject.verbose_name[ModelObject.verbose_name} */ - static get verbose_name() { return 'article_category'; } + static get verbose_name() { return 'category'; } /** * @default {@link Formatters.ArticleCategoryFormatter} @@ -589,13 +589,6 @@ class ModelList { }); } - /** - * 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=[]] @@ -664,31 +657,32 @@ class ModelList { } /** - * Renders an element (and all its offspring) and appends it to the given container. - * Returns the completed container - * @param {jQuery} $container + * Renders an element (and all its offspring) and returns the + * corresponding jQuery object. * @param {Models.ModelObject} elt + * @param {Object} templates Templates to render each model * @param {Object} [options] Options for element render method */ - render_element($container, elt, options) { - var depth = this.names.indexOf(elt.constructor.verbose_name); + render_element(elt, templates, options) { + var name = elt.constructor.verbose_name; + var depth = this.names.indexOf(name); + var template = templates[name]; if (depth == -1) { return $(); } else if (depth == 0) { - $container.append(elt.display($(this.constructor.templates[0]), options)); - return $container; + return elt.display($(template), options); } 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)); + $container = elt.display($(template), options); + $container.attr('data'+name+'id', elt.id); for (let child of children) { - this.render_element($container, child, options); + $container.append(this.render_element(child, templates, options)); } return $container; @@ -698,21 +692,110 @@ class ModelList { /** * 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, options) { + display($container, templates, 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); + $container.append(this.render_element(root, templates, options); } return $container; } + + /** + * Find instance in data matching given properties. + * @param {class} model + * @param {Object} props Properties to match + */ + find(model, props) { + if (!this.constructor.models.find(model)) { + return undefined ; + } + + return this.data[model.verbose_name].find(function(v) { + for (let key in props) { + if (v[key] !== props[key]) + return false; + } + return true; + }); + } } + +/** + * Describes a model list that can be filled through API. + * @extends Models.ModelList + * @memberof Models + */ +class APIModelList extends ModelList { + + /** + * Request url to fill the model. + * @abstract + * @type {string} + */ + static get url_model() {} + + /** + * Fills the instance with distant data. It sends a GET HTTP request to + * {@link Models.APIModelList#url_model}. + * @param {object} [api_options] Additional data appended to the request. + * @param {jQueryAjaxSuccess} [on_success] A function to be called if the request succeeds. + * @param {jQueryAjaxError} [on_error] A function to be called if the request fails. + */ + fromAPI(api_options, on_success, on_error) { + var that = this; + + api_options = api_options || {} + on_success = on_success || $.noop; + on_error = on_error || $.noop; + + api_options['format'] = 'json'; + + $.getJSON(this.url_model, api_options) + .done(function(json, textStatus, jqXHR) { + that.from(json); + on_success(json, textStatus, jqXHR); + }) + .fail(on_error); + } +} + + +/** + * ArticleList model. Can be accessed through API. + * @extends Models.APIModelList + * @memberof Models + */ +class ArticleList extends APIModelList { + + /** + * Default structure for ArticleList instances + * @abstract + * @default [Article, ArticleCategory] + */ + static get models() { + return [Article, ArticleCategory]; + } + + /** + * Default url to get ArticlList data + * @abstract + * @default django-js-reverse('kfet.kpsul.articles_data') + * @see {@link Models.APIModelList.url_model|APIModelList.url_model} + */ + static get url_model { + return Urls['kfet.kpsul.articles_data']; + } + + + /* ---------- ---------- */ /**