CartoDB/cartodb20

View on GitHub
lib/assets/javascripts/dashboard/data/visualizations-collection.js

Summary

Maintainability
C
1 day
Test Coverage
const Backbone = require('backbone');
const _ = require('underscore');
const $ = require('jquery');
const VisualizationModel = require('dashboard/data/visualization-model');
const checkAndBuildOpts = require('builder/helpers/required-opts');

const REQUIRED_OPTS = [
  'configModel'
];

/**
 * Visualizations endpoint available for a given user.
 *
 * Usage:
 *
 *   const visualizations = new VisualizationsCollection();
 *   visualizations.fetch();
 *
 */

module.exports = Backbone.Collection.extend({

  _PREVIEW_TABLES_PER_PAGE: 10,
  _TABLES_PER_PAGE: 20,
  _PREVIEW_ITEMS_PER_PAGE: 3,
  _ITEMS_PER_PAGE: 9,

  sync: require('dashboard/data/backbone/sync-abort'),

  initialize: function (models, opts) {
    checkAndBuildOpts(opts, REQUIRED_OPTS, this);

    var default_options = new Backbone.Model({
      tag_name: '',
      q: '',
      page: 1,
      type: 'derived',
      exclude_shared: false,
      per_page: this._ITEMS_PER_PAGE
    });

    this.options = _.extend(default_options, this.options);

    this.total_entries = 0;

    this.bind('reset', this._checkPage, this);
  },

  model: function (attrs, opts) {
    const options = { ...opts, configModel: opts.collection._configModel };

    return new VisualizationModel(attrs, options);
  },

  getTotalPages: function () {
    return Math.ceil(this.total_entries / this.options.get('per_page'));
  },

  _checkPage: function () {
    const total = this.getTotalPages();

    if (this.options.get('page') > total) {
      this.options.set({ page: total + 1 });
    } else if (this.options.get('page') < 1) {
      this.options.set({ page: 1 });
    }
  },

  _createUrlOptions: function () {
    const urlParams = _(this.options.attributes).map((v, k) => `${k}=${encodeURIComponent(v)}`);

    return _.compact(urlParams).join('&');
  },

  url: function (method) {
    const version = this._configModel.urlVersion('visualizations', method);

    return `/api/${version}/viz?${this._createUrlOptions()}`;
  },

  remove: function (options) {
    this.total_entries--;

    Backbone.Collection.prototype.remove.apply(this, arguments);
  },

  // add bindMap: false for all the visulizations
  // vis model does not need map information in dashboard
  parse: function (response) {
    this.total_entries = response.total_entries;
    this.slides && this.slides.reset(response.children);
    this.total_shared = response.total_shared;
    this.total_likes = response.total_likes;
    this.total_user_entries = response.total_user_entries;

    return response.visualizations.map(vis => ({ ...vis, bindMap: false }));
  },

  create: function (model) {
    const deferred = $.Deferred();

    Backbone.Collection.prototype.create.call(this,
      model,
      {
        wait: true,
        success: () => deferred.resolve(),
        error: () => deferred.reject()
      }
    );

    return deferred.promise();
  },

  fetch: function (opts) {
    var deferred = $.Deferred();
    var self = this;

    this.trigger('loading', this);

    $.when(Backbone.Collection.prototype.fetch.call(this, opts))
      .done(function (res) {
        self.trigger('loaded');
        deferred.resolve();
      })
      .fail(function (res) {
        self.trigger('loadFailed');
        deferred.reject(res);
      });

    return deferred.promise();
  },

  getTotalStat: function (attribute) {
    return this[attribute] || 0;
  },

  getDefaultParam: function (param) {
    return this.options.get(param);
  }
});