CartoDB/cartodb20

View on GitHub
lib/assets/javascripts/builder/data/user-model.js

Summary

Maintainability
D
2 days
Test Coverage
var Backbone = require('backbone');
var _ = require('underscore');
var OrganizationModel = require('./organization-model');
var UserGroups = require('./user-groups-collection');
var CustomBaselayersCollection = require('./custom-baselayers-collection');
/**
 *  User model
 *
 */

var UserModel = Backbone.Model.extend({
  urlRoot: function () {
    var baseUrl = this._configModel.get('base_url');
    return baseUrl + '/api/v1/users';
  },

  defaults: {
    avatar_url: 'http://cartodb.s3.amazonaws.com/static/public_dashboard_default_avatar.png',
    username: '',
    email: ''
  },

  initialize: function (attrs, opts) {
    if (!opts.configModel) throw new Error('configModel is required');
    this._configModel = opts.configModel;
    attrs = attrs || {};

    if (!_.isEmpty(this.get('organization'))) {
      this._organizationModel = new OrganizationModel(
        this.get('organization'),
        {
          configModel: this._configModel,
          currentUserId: this.id
        }
      );
    }

    if (this.get('layers')) {
      this.layers = new CustomBaselayersCollection(this.get('layers'), {
        configModel: this._configModel,
        currentUserId: this.id
      });
    }

    this.groups = new UserGroups(attrs.groups, {
      organization: this._organizationModel
    });
  },

  // Type of user
  isViewer: function () {
    return this.get('viewer') === true;
  },

  isBuilder: function () {
    return !this.isViewer();
  },

  // Org-related
  isInsideOrg: function () {
    if (this._organizationModel) {
      return !!this._organizationModel.id || this.isOrgOwner();
    }
    return false;
  },

  isOrgOwner: function () {
    if (this._organizationModel) {
      return this._organizationModel.getOwnerId() === this.get('id');
    }
    return false;
  },

  isOrgAdmin: function () {
    if (this._organizationModel) {
      return this._organizationModel.isOrgAdmin(this);
    }
    return false;
  },

  getOrganization: function () {
    return this._organizationModel;
  },

  isDOEnabled: function () {
    return this.get('do_enabled');
  },

  // Plan-related
  isEnterprise: function () {
    return this.get('is_enterprise');
  },

  isIndividualUser: function () {
    const proUsers = ['Individual', 'Annual Individual'];
    return proUsers.indexOf(this.get('account_type')) > -1;
  },

  isFree2020User: function () {
    const proUsers = ['Free 2020'];
    return proUsers.indexOf(this.get('account_type')) > -1;
  },

  // Limits & quotas
  hasRemainingByteQuota: function () {
    return !(!this.get('remaining_byte_quota') || this.get('remaining_byte_quota') <= 0);
  },

  hasTableLimits: function () {
    return this.isIndividualUser() || this.isFree2020User();
  },

  hasRemainingTableCount: function () {
    if (this.hasTableLimits()) {
      return !(!this.get('table_count') || this.get('table_count') >= this.get('table_quota'));
    }
    return true;
  },

  canCreateDatasets: function () {
    if (this.hasRemainingByteQuota() && this.hasRemainingTableCount()) {
      return true;
    }
    return false;
  },

  updateTableCount: function () {
    var currentTableCount = this.get('table_count');
    if (currentTableCount) {
      this.set('table_count', currentTableCount + 1);
    }
  },

  hasPublicMapsLimits: function () {
    const userWithLimits = this.isIndividualUser() || this.isFree2020User();
    return userWithLimits && !this.hasUnlimitedPublicMaps();
  },

  hasRemainingPublicMaps: function () {
    if (this.hasPublicMapsLimits()) {
      return this.get('public_map_quota') > this.getTotalPublicMapsCount();
    }
    return true;
  },

  hasUnlimitedPublicMaps: function () {
    return this.get('public_map_quota') === null;
  },

  getTotalPublicMapsCount: function () {
    var totalPublicPrivacyMapsCount = this.get('public_privacy_map_count') || 0;
    var totalPasswordPrivacyMapsCount = this.get('password_privacy_map_count') || 0;
    var totalLinkPrivacyMapsCount = this.get('link_privacy_map_count') || 0;

    return totalPublicPrivacyMapsCount + totalPasswordPrivacyMapsCount + totalLinkPrivacyMapsCount;
  },

  hasPrivateMapsLimits: function () {
    const userWithLimits = this.isFree2020User();
    return userWithLimits && !this.hasUnlimitedPrivateMaps();
  },

  hasRemainingPrivateMaps: function () {
    if (this.hasPrivateMapsLimits()) {
      return this.get('private_map_quota') > this.getTotalPrivateMapsCount();
    }
    return true;
  },

  hasUnlimitedPrivateMaps: function () {
    return this.get('private_map_quota') === null;
  },

  getTotalPrivateMapsCount: function () {
    return this.get('private_privacy_map_count');
  },

  canCreatePrivateDatasets: function () {
    var actions = this.get('actions');
    return actions && actions.private_tables;
  },

  hasCreateMapsFeature: function () {
    return this.isBuilder();
  },

  canCreateTwitterDataset: function () {
    return this.hasOwnTwitterCredentials();
  },

  hasOwnTwitterCredentials: function () {
    var twitter = this.get('twitter');
    return (twitter && twitter.customized_config) || false;
  },

  canSelectPremiumOptions: function (visModel) {
    return this.get('actions')[ visModel.isVisualization() ? 'private_maps' : 'private_tables' ];
  },

  canStartTrial: function () {
    return !this.isInsideOrg() && this.get('account_type') === 'FREE' && this.get('table_count') > 0;
  },

  // Public sharing
  hasPublicMapSharingDisabled: function () {
    return this.get('public_map_quota') === 0;
  },

  hasPublicDatasetSharingDisabled: function () {
    return this.get('public_dataset_quota') === 0;
  },

  // Utils
  isActionEnabled: function (action) {
    return this.get('actions') && this.get('actions')[action];
  },

  hasAccountType: function (accountType) {
    return this.get('account_type') === accountType;
  },

  featureEnabled: function (name) {
    var featureFlags = this.get('feature_flags');
    if (!featureFlags || featureFlags.length === 0 || !name) {
      return false;
    }
    return _.contains(featureFlags, name);
  },

  upgradeContactEmail: function () {
    if (this.isInsideOrg()) {
      if (this.isOrgOwner()) {
        return 'enterprise-support@carto.com';
      } else {
        return this._organizationModel.getOwnerEmail();
      }
    } else {
      return 'support@carto.com';
    }
  },

  nameOrUsername: function () {
    return this.fullName() || this.get('username');
  },

  fullName: function () {
    var name = this.get('name') || '';
    var lastName = this.get('last_name') || '';
    if (name || lastName) {
      return name + (name && lastName ? ' ' : '') + lastName;
    }
    return '';
  },

  getMaxConcurrentImports: function () {
    return (this.get('limits') && this.get('limits').concurrent_imports) || 1;
  },

  getSchemaName: function () {
    return this.isInsideOrg() ? this.get('username') : 'public';
  },

  renderData: function (currentUser) {
    var name = this.get('username');
    if (currentUser && currentUser.id === this.id) {
      name = _t('user.you');
    }
    return {
      username: name,
      avatar_url: this.get('avatar_url')
    };
  },

  clone: function () {
    var attrs = _.clone(this.attributes);
    delete attrs.id;
    return new UserModel(attrs, {
      configModel: this._configModel
    });
  }
});

module.exports = UserModel;