Initial commit

This commit is contained in:
zhongjin
2020-06-15 10:58:47 +08:00
commit 4f1dfe7564
8590 changed files with 1516878 additions and 0 deletions
@@ -0,0 +1,15 @@
<div class="ApiKeysCTA-container">
<div class="u-flex u-justifySpace">
<div>
<p class="CDB-Text CDB-Size-large">Your plan doesn't include API keys</p>
<div class="u-flex u-justifySpace u-tSpace--m">
<p class="CDB-Text CDB-Size-medium u-altTextColor">Upgrade your plan to start developing custom applications with our suite of frontend libraries and APIs, and integrating spatial data into your Python scripts. Learn more about
<a href="https://carto.com/developers/fundamentals/authorization/" class="CDB-Text CDB-Size-medium" target="_blank">API keys</a>.
</p>
<div>
<a href="<%= current_user.upgrade_url(request.protocol) %>" class="u-iblock CDB-Button CDB-Button--primary CDB-Text CDB-Size-medium is-semibold u-whiteSpace-nowrap">Upgrade now</a>
</div>
</div>
</div>
</div>
</div>
@@ -0,0 +1,77 @@
<div class="ApiKeysForm-container">
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor FormAccount-label">Your API Key</label>
</div>
<div class="FormAccount-rowData">
<input type="text" class="CDB-InputText CDB-Text FormAccount-input FormAccount-input--long" placeholder="No API key" value="<%= current_user.api_key %>" readonly />
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
<a class="CDB-Size-medium js-regenerateApiKey" href="#">Request a new API key</a>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor FormAccount-label FormAccount-label--verticalAlignTop">Example write</label>
</div>
<div class="FormAccount-rowPreview">
<% if CartoDB.subdomainless_urls? %>
<p class="CDB-Size-small FormAccount-text FormAccount-text--preview">https://<%= CartoDB.account_host %>/user/<%= current_user.username %>/api/v2/sql?q=INSERT INTO table_name (the_geom, observation) VALUES (ST_GeomFromText(’POINT(-71.2 42.5)’, 4326),'rare bird spotted')&api_key=<%= current_user.api_key %></p>
<% else %>
<p class="CDB-Size-small FormAccount-text FormAccount-text--preview">https://<%= current_user.username %>.<%= CartoDB.account_host %>/api/v2/sql?q=INSERT INTO table_name (the_geom, observation) VALUES (ST_GeomFromText(’POINT(-71.2 42.5)’, 4326),'rare bird spotted')&api_key=<%= current_user.api_key %></p>
<% end%>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor FormAccount-label FormAccount-label--verticalAlignTop">Example read private</label>
</div>
<div class="FormAccount-rowPreview">
<% if CartoDB.subdomainless_urls? %>
<p class="CDB-Size-small FormAccount-text FormAccount-text--preview">https://<%= CartoDB.account_host %>/user/<%= current_user.username %>/api/v2/sql?q=SELECT * FROM private_table&api_key=<%= current_user.api_key %></p>
<% else %>
<p class="CDB-Size-small FormAccount-text FormAccount-text--preview">https://<%= current_user.username %>.<%= CartoDB.account_host %>/api/v2/sql?q=SELECT * FROM private_table&api_key=<%= current_user.api_key %></p>
<% end %>
</div>
</div>
<% if show_google_api_keys?(current_user) %>
<div class="FormAccount-title">
<p class="FormAccount-titleText">Configure API keys from external providers</p>
</div>
<span class="FormAccount-separator"></span>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor FormAccount-label">Google Maps</label>
</div>
<div class="FormAccount-rowData">
<input type="text" value="<%= current_user.organization.present? ? current_user.organization.google_maps_private_key : current_user.google_maps_private_key %>" class="CDB-InputText CDB-Text FormAccount-input FormAccount-input--long is-disabled" readonly />
</div>
<div class="FormAccount-rowInfo">
<% if !current_user.organization.present? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">
This is your Google Maps query string, contact with <a href="mailto:support@carto.com">support@carto.com</a> to change it.
</p>
<% elsif current_user.organization.present? && current_user.organization_owner? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">
This is the <%= current_user.organization.name %> Google Maps query string, contact with <a href="mailto:support@carto.com">support@carto.com</a> to change it.
</p>
<% else %>
<p class="CDB-Text CDB-Size-small u-altTextColor">This is the organization Google Maps API key</p>
<% end %>
</div>
</div>
<% end %>
</div>
<div class="FormAccount-footer">
<p class="FormAccount-footerText">
<i class="CDB-IconFont CDB-IconFont-info FormAccount-footerIcon"></i>
<span>Learn more about location app authorization and API key management <%= link_to "here", "https://carto.com/developers/fundamentals/authorization/" %></span>
</p>
</div>
@@ -0,0 +1,45 @@
<% content_for(:page_title) do %>
Your API keys |
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var username = "<%= current_user.username %>";
var config = <%= safe_js_object frontend_config %>;
var user_data = <%= safe_js_object current_user.data.to_json %>;
var upgrade_url = "<%= current_user.upgrade_url(request.protocol) %>";
var mobile_enabled = "<%= current_user.mobile_sdk_enabled? %>";
var dashboardNotifications = <%= safe_js_object @dashboard_notifications.to_json %>;
var organization_notifications = <%= safe_js_object @organization_notifications.to_json %>;
</script>
<%= javascript_include_tag 'common', 'common_vendor', 'api_keys_new' %>
<% end %>
<%= content_for(:css) do %>
<% if @has_engine_enabled %>
<%= stylesheet_link_tag 'api_keys_new', :media => 'all' %>
<% else %>
<%= editor_stylesheet_link_tag 'api_keys', :media => 'all' %>
<% end %>
<% end %>
<%= render :partial => 'shared/flash_message' %>
<%= render :partial => 'admin/shared/trial_notification' %>
<div class="FormAccount-Section u-inner">
<%= render :partial => 'admin/shared/pages_subheader' %>
<div class="CDB-Text FormAccount-Content">
<%= render :partial => 'admin/shared/api_keys_subheader' %>
<% if @has_engine_enabled %>
<div class="api-keys js-api-keys-new"></div>
<% else %>
<%= render :partial => 'api_keys_cta' %>
<% end %>
</div>
</div>
<%= render 'admin/shared/new_private_footer' %>
@@ -0,0 +1,92 @@
<% content_for(:page_title) do %>
Your OAuth credentials |
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var username = "<%= current_user.username %>";
var config = <%= safe_js_object frontend_config %>;
var user_data = <%= safe_js_object current_user.data.to_json %>;
var upgrade_url = "<%= current_user.upgrade_url(request.protocol) %>";
</script>
<%= editor_javascript_include_tag 'cdb.js', 'models.js', 'keys_templates.js', 'keys_deps.js', 'keys.js' -%>
<% end %>
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'keys.css', :media => 'all' %>
<% end %>
<%= render :partial => 'shared/flash_message' %>
<div class="FormAccount-Section u-inner">
<%= render :partial => 'admin/shared/pages_subheader' %>
<div class="FormAccount-Content">
<div class="FormAccount-title">
<p class="FormAccount-titleText">Approve applications to act on their behalf without sharing your password</p>
</div>
<span class="FormAccount-separator"></span>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="FormAccount-label">Consumer key</label>
</div>
<div class="FormAccount-rowData">
<input type="text" class="FormAccount-input FormAccount-input--long has-icon js-input" value="<%= current_user.client_application.key %>" readonly />
<i data-title="Copy this" class="CDB-IconFont CDB-IconFont-anchor FormAccount-inputIcon FormAccount-copyIcon js-copy-value"></i>
</div>
<div class="FormAccount-rowInfo">
<p class="FormAccount-rowInfoText">Learn more about <%= link_to "using oauth in CARTO", Cartodb.config[:developers_host] + "/cartodb-platform.html" %>.</p>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="FormAccount-label">Consumer secret</label>
</div>
<div class="FormAccount-rowData">
<input type="text" class="FormAccount-input FormAccount-input--long has-icon js-input" value="<%= current_user.client_application.secret %>" readonly />
<i data-title="Copy this" class="CDB-IconFont CDB-IconFont-anchor FormAccount-inputIcon FormAccount-copyIcon js-copy-value"></i>
</div>
</div>
<span class="FormAccount-separator FormAccount-separator--marginTop"></span>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="FormAccount-label">Request token URL</label>
</div>
<div class="FormAccount-rowData">
<input type="text" class="FormAccount-input FormAccount-input--long has-icon js-input" value="<%= CartoDB.url(self, 'request_token', user: current_user) %>" readonly />
<i data-title="Copy this" class="CDB-IconFont CDB-IconFont-anchor FormAccount-inputIcon FormAccount-copyIcon js-copy-value"></i>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="FormAccount-label">Access token URL</label>
</div>
<div class="FormAccount-rowData">
<input type="text" class="FormAccount-input FormAccount-input--long has-icon js-input" value="<%= CartoDB.url(self, 'access_token', user: current_user) %>" readonly />
<i data-title="Copy this" class="CDB-IconFont CDB-IconFont-anchor FormAccount-inputIcon FormAccount-copyIcon js-copy-value"></i>
</div>
</div>
<div class="FormAccount-footer">
<p class="FormAccount-footerText">
<i class="CDB-IconFont CDB-IconFont-info FormAccount-footerIcon"></i>
<span>Learn more about location app authorization and API key management <%= link_to "here", "https://carto.com/developers/fundamentals/authorization/" %></span>
</p>
<p class="FormAccount-footerText">
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" />
<a class="js-regenerateOauth Button Button--main" href="#"><span>Generate new keys</span></a>
</p>
</div>
</div>
</div>
<%= render 'admin/shared/new_private_footer' %>
@@ -0,0 +1,335 @@
<%= form_for @user, url: (@user.new? ? CartoDB.url(self, 'create_organization_user', user: current_user) : CartoDB.url(self, 'update_organization_user', params: { id: @user.username }, user: current_user)), :html => {:class => 'Form js-organizationUserForm CDB-Text'} do |f| %>
<%= f.hidden_field :private_tables_enabled %>
<%= hidden_field_tag :show_account_settings_flash, true %>
<%= csrf_meta_tags %>
<span class="FormAccount-separator"></span>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Username</label>
</div>
<div class="FormAccount-rowData">
<%= f.text_field :username, :class => "CDB-InputText CDB-Text FormAccount-input FormAccount-input--med #{ 'is-disabled' if !@user.new? } #{ 'has-error' if @user.errors[:username].present? }", :readonly => !@user.new? %>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<% if (@user.errors[:username].present?) %>
<p class="FormAccount-rowInfoText FormAccount-rowInfoText--error u-tSpace">Username not valid</p>
<% elsif @user.new? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">Once you choose the username, you won't be able to change it</p>
<% end %>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Email</label>
</div>
<div class="FormAccount-rowData">
<%= f.text_field :email, :class => "CDB-InputText CDB-Text FormAccount-input FormAccount-input--med #{ 'is-disabled' if !@user.can_change_email? } #{ 'has-error' if @user.errors[:email].present? }", readonly: !@user.can_change_email? %>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<% if (@user.errors[:email].present?) %>
<p class="CDB-Text CDB-Size-small u-altTextColor FormAccount-rowInfoText--error">Email not valid</p>
<% elsif @user.new? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">We encourage you to choose an email from your organization</p>
<% end %>
</div>
</div>
</div>
<% if @organization.auth_username_password_enabled %>
<div class="VerticalAligned--FormRow">
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">New password</label>
</div>
<div class="FormAccount-rowData">
<%= password_field_tag 'user[password]', nil, :placeholder => "New password", :class => "CDB-InputText CDB-Text FormAccount-input FormAccount-input--med #{ 'is-disabled' if !@user.can_change_password? } #{ 'has-error' if @user.errors[:password].present? }", readonly: !@user.can_change_password? %>
</div>
<div class="FormAccount-rowInfo">
<% if (@user.errors[:password].present?) %>
<p class="FormAccount-rowInfoText FormAccount-rowInfoText--error u-tSpace"><%= @user.errors[:password].first%></p>
<% end %>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Confirm password</label>
</div>
<div class="FormAccount-rowData">
<%= password_field_tag 'user[password_confirmation]', nil, :placeholder => "Confirm new password", :class => "CDB-InputText CDB-Text FormAccount-input FormAccount-input--med #{ 'is-disabled' if !@user.can_change_password? } #{ 'has-error' if @user.errors[:password].present?}", readonly: !@user.can_change_password? %>
</div>
</div>
</div>
<% end %>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">User type</label>
</div>
<div class="FormAccount-rowData">
<div class="CDB-Text CDB-Size-medium u-rSpace--xl">
<input class="CDB-Radio js-userViewerOption" type="radio" name="user[viewer]" value="false" <%= @user.builder? ? 'checked' : '' %> <%= @organization.remaining_seats > 0 || @user.builder? ? '' : 'disabled' %> required>
<span class="u-iBlock CDB-Radio-face"></span>
<label class="u-iBlock u-lSpace CDB-Text CDB-Size-medium u-secondaryTextColor is-semibold">Builder (<%= @organization.assigned_seats %>/<%= @organization.seats %>)</label>
</div>
</div>
<div class="FormAccount-rowInfo u-lspace-23 u-bSpace--xl">
<p class="FormAccount-rowInfoText">Build and read</p>
</div>
<% admin_editing_admin = @user.organization_admin? && !current_user.organization_owner? %>
<div class="FormAccount-rowData">
<div class="CDB-Text CDB-Size-medium u-rSpace--xl">
<input class="CDB-Radio js-userViewerOption" type="radio" name="user[viewer]" value="true" <%= @user.viewer? ? 'checked' : '' %> <%= (@organization.remaining_viewer_seats == 0 && !@user.viewer?) || @user.organization_owner? || admin_editing_admin ? 'disabled' : '' %> required>
<span class="u-iBlock CDB-Radio-face"></span>
<label class="u-iBlock u-lSpace CDB-Text CDB-Size-medium u-secondaryTextColor is-semibold">Viewer (<%= @organization.assigned_viewer_seats %>/<%= @organization.viewer_seats %>)</label>
</div>
</div>
<div class="FormAccount-rowInfo u-lspace-23">
<p class="FormAccount-rowInfoText">
<% if @user.organization_owner? %>
The organization owner cannot be a viewer user.
<% elsif admin_editing_admin %>
Organization admins can only be builder users.
<% elsif @organization.viewer_seats == 0 %>
You don't have viewer seats activated. <a href="mailto:enterprise-support@carto.com">Contact support</a> for more information.
<% else %>
Only read
<% end %>
</p>
</div>
</div>
<% if !@user.organization_owner? %>
<div class="FormAccount-row js-org-admin-row" <%= @user.builder? ? 'style="display: none;"' : '' %>>
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Administrator</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :org_admin, id: "org_admin", disabled: !current_user.organization_owner? %>
<%= label_tag(:org_admin, '') %>
</div>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<p class="CDB-Text CDB-Size-small u-altTextColor">
<% if current_user.organization_owner? %>
User has permission to manage users and groups and send notifications
<% else %>
Only the organization owner can assign administrator rights
<% end %>
</p>
</div>
</div>
</div>
<% end %>
<% mfa_configured = @user.multifactor_authentication_configured? %>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">
Multi-factor authentication
</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :mfa, id: "mfa", checked: mfa_configured %>
<%= label_tag(:mfa, '') %>
</div>
<div class="FormAccount-rowInfo u-lspace-23">
<p class="CDB-Text CDB-Size-small u-altTextColor">
If you change the Multi-factor authentication, it will be available only for this user. When you change the status, the user will be logged out and redirected to the login page.
</p>
</div>
</div>
</div>
<div class="user-quotas" style="display: none">
<div class="FormAccount-title">
<p class="FormAccount-titleText">User quotas</p>
</div>
<span class="FormAccount-separator"></span>
<div class="FormAccount-row">
<div class="OrganizationUser-quota js-userQuota">
<div class="FormAccount-rowData FormAccount-rowData--med OrganizationUser-quotaProgress js-userQuotaSlider">
<div class="UISlider UserQuotaDropdown-slider js-slider progress-bar overflow-visible">
<% available_quota_for_user = @organization.unassigned_quota + @user.quota_in_bytes %>
<% assignedPer = ((@user.quota_in_bytes.to_f * 100) / available_quota_for_user) %>
<% if !@user.new? %>
<% usedPer = ((@user.db_size_in_bytes.to_f * 100) / available_quota_for_user) %>
<span class="js-usedUserQuota bar-3" style="width:<%= usedPer %>%"></span>
<% end %>
</div>
<ul class="OrganizationUser-quotaLegend">
<% if !@user.new? %>
<li class="OrganizationUser-quotaLegendItem CDB-Size-small">
<i class="OrganizationUser-quotaLegendIcon OrganizationUser-quotaLegendIcon--used"></i>
Used by user
</li>
<% end %>
<li class="OrganizationUser-quotaLegendItem CDB-Size-small">
<i class="OrganizationUser-quotaLegendIcon OrganizationUser-quotaLegendIcon--assigned"></i>
Assigned to user
</li>
<li class="OrganizationUser-quotaLegendItem CDB-Size-small">
<i class="OrganizationUser-quotaLegendIcon"></i>
Total
</li>
</ul>
</div>
<div class="FormAccount-rowInfo u-lSpace--xl OrganizationUser-quotaInfo js-userQuotaSliderInput CDB-Text CDB-Size-medium u-altTextColor">
<span><%= text_field_tag nil, nil, :class => "CDB-InputText CDB-Text FormAccount-input OrganizationUser-quotaInfoInput js-assignedSize" %> MB<% unless cartodb_com_hosted? %>, <a href="<%= current_user.upgrade_url(request.protocol) %>">upgrade your account</a> if needed.<% end %></span>
</div>
<%= f.hidden_field :quota_in_bytes, :id => "user_quota" %>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Extra geocoding</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :soft_geocoding_limit, id: "soft_geocoding_limit", disabled: !@organization.soft_geocoding_limit? %>
<%= label_tag(:soft_geocoding_limit, '') %>
</div>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<% if @organization.soft_geocoding_limit? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">User has permission to exceed organization's geocoding quota</p>
<% else %>
<p class="CDB-Text CDB-Size-small u-altTextColor">You can't enable extra quota. Contact support for more information.</p>
<% end %>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Extra Here Isolines</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :soft_here_isolines_limit, id: "soft_here_isolines_limit", disabled: !@organization.soft_here_isolines_limit? %>
<%= label_tag(:soft_here_isolines_limit, '') %>
</div>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<% if @organization.soft_here_isolines_limit? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">User has permission to exceed organization's isolines quota from Here provider</p>
<% else %>
<p class="CDB-Text CDB-Size-small u-altTextColor">You can't enable extra quota. Contact support for more information.</p>
<% end %>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Extra Routing API calls</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :soft_mapzen_routing_limit, id: "soft_mapzen_routing_limit", disabled: !@organization.soft_mapzen_routing_limit? %>
<%= label_tag(:soft_mapzen_routing_limit, '') %>
</div>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<% if @organization.soft_mapzen_routing_limit? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">User has permission to exceed organization's routing quota from Mapzen provider</p>
<% else %>
<p class="CDB-Text CDB-Size-small u-altTextColor">You can't enable extra quota. Contact support for more information.</p>
<% end %>
</div>
</div>
</div>
<% if @organization.twitter_datasource_enabled %>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Extra tweets</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :soft_twitter_datasource_limit, id: "soft_twitter_datasource_limit", disabled: !@organization.soft_twitter_datasource_limit? %>
<%= label_tag(:soft_twitter_datasource_limit, '') %>
</div>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<% if @organization.soft_twitter_datasource_limit? %>
<p class="CDB-Text CDB-Size-small u-altTextColor">User has permission to exceed organization's Twitter credits</p>
<% else %>
<p class="CDB-Text CDB-Size-small u-altTextColor">You can't enable extra quota. Contact support for more information.</p>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
<% if !@user.new? && current_user.organization_owner? && @user.engine_enabled? -%>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">User master API key</label>
</div>
<div class="FormAccount-rowData">
<%= f.text_field :api_key, :class => "CDB-InputText CDB-Text FormAccount-input FormAccount-input--med is-disabled", :readonly => true %>
<div class="FormAccount-rowInfo FormAccount-rowInfo--marginLeft">
<button class="CDB-Text CDB-Size-medium Button--link js-regenerateOrgUserApiKey" data-username="<%= @user.username %>" data-current_username="<%= current_user.username %>" type="button">Regenerate all API keys</button>
</div>
</div>
</div>
<% end %>
<% if @user.new? -%>
<% if @organization.remaining_seats > 0 || @organization.remaining_viewer_seats > 0 %>
<div class="FormAccount-footer u-justifyEnd">
<button type="submit" class="CDB-Button CDB-Button--primary js-save">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Create user</span>
</button>
</div>
<% else %>
<div class="FormAccount-footer">
<p class="FormAccount-rowInfoText FormAccount-rowInfoText--maxWidth">You can't create new users because you've run out of seats. <a href="mailto:enterprise-support@carto.com">Contact support</a> for more information.</p>
<button type="submit" class="CDB-Button CDB-Button--primary is-disabled js-save">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Create user</span>
</button>
</div>
<% end %>
<% elsif @user.editable_by?(current_user) %>
<% if @user != current_user %>
<div class="FormAccount-footer">
<button href="<%= CartoDB.url(self, 'delete_organization_user', params: { id: @user.username }, user: current_user) %>" type="button" class="CDB-Button CDB-Button--error js-deleteAccount">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Delete user</span>
</button>
<button type="submit" class="CDB-Button CDB-Button--primary js-save">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Save changes</span>
</button>
</div>
<% else %>
<div class="FormAccount-footer u-justifyEnd">
<button class="CDB-Button CDB-Button--primary js-save">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Save changes</span>
</button>
</div>
<% end %>
<% end %>
<% end %>
<script type="text/javascript">
<% if !@user.new? %>
var organization_user_data = <%= safe_js_object @user.data.to_json %>;
<% else %>
<% @user.values[:db_size_in_bytes] = 0 %>
<% @user.values[:organization] = current_user.data[:organization] %>
<% @user.values[:quota_available_for_user] = current_user.data[:organization][:unassigned_quota] + @user.values[:quota_in_bytes] %>
var organization_user_data = <%= safe_js_object @user.values.to_json %>;
<% end %>
</script>
@@ -0,0 +1,51 @@
<% content_for(:page_title) do %>
Edit <%= @user.username %> |
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var username = "<%= current_user.username %>";
var authenticity_token = "<%= form_authenticity_token %>";
var config = <%= safe_js_object frontend_config %>;
var user_data = <%= safe_js_object current_user.data.to_json.html_safe %>;
var mobile_enabled = "<%= current_user.mobile_sdk_enabled? %>"
</script>
<%= javascript_include_tag 'common', 'common_vendor', 'organization' %>
<% end %>
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'organization.css', :media => 'all' %>
<% end %>
<%= render :partial => 'shared/flash_message' %>
<div class="FormAccount-Section u-inner">
<%= render :partial => 'admin/shared/pages_subheader' %>
<div class="FormAccount-Content">
<div class="Filters is-relative">
<div class="Filters-inner">
<span class="Filters-separator"></span>
<div class="Filters-row">
<ul class="Filters-group CDB-Text CDB-Size-medium">
<li class="u-flex u-alignCenter">
<a href="<%= current_user_url('organization') %>" class="u-actionTextColor u-flex u-alignCenter">
<i class="CDB-IconFont CDB-IconFont-arrowPrev u-rSpace--xl"></i>
</a>
</li>
<li class="Filters-typeItem">
<div class="FormAccount-title">
<p class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor"><%= @user.username.capitalize %></p>
</div>
</li>
</ul>
</div>
</div>
</div>
<%= render partial: 'form' %>
</div>
</div>
<%= render 'admin/shared/new_private_footer' %>
@@ -0,0 +1,46 @@
<% content_for(:page_title) do %>
New <%= current_user.organization.name %> user |
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var username = "<%= current_user.username %>";
var config = <%= safe_js_object frontend_config %>;
var user_data = <%= safe_js_object current_user.data.to_json.html_safe %>;
</script>
<%= javascript_include_tag 'common', 'common_vendor', 'organization' %>
<% end %>
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'organization.css', :media => 'all' %>
<% end %>
<%= render :partial => 'shared/flash_message' %>
<div class="FormAccount-Section u-inner">
<%= render :partial => 'admin/shared/pages_subheader' %>
<div class="FormAccount-Content">
<div class="Filters is-relative">
<div class="Filters-inner">
<span class="Filters-separator"></span>
<div class="Filters-row">
<ul class="Filters-group CDB-Text CDB-Size-medium">
<li class="u-flex u-alignCenter">
<a href="<%= current_user_url('organization') %>" class="u-actionTextColor u-flex u-alignCenter">
<i class="CDB-IconFont CDB-IconFont-arrowPrev u-rSpace--xl"></i>
</a>
</li>
<li class="Filters-typeItem">
<div class="FormAccount-title">
<p class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">New user</p>
</div>
</li>
</ul>
</div>
</div>
</div>
<%= render partial: 'form' %>
</div>
</div>
<%= render 'admin/shared/new_private_footer' %>
@@ -0,0 +1,73 @@
<div class="FormAccount-title">
<p class="FormAccount-titleText">LDAP Configuration</p>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Host</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.host %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Port</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.port %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Encryption</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.encryption %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Certificate file (if any)</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.ca_file %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">SSL Version</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.ssl_version %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Connection user</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.connection_user %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Connection password</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.connection_password %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">User Id. field</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.user_id_field %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Username field</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.username_field %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">User email field</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.email_field %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Domain bases</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.domain_bases %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Additional search filter</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.additional_search_filter %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">User object class</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.user_object_class %></div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel"><label class="FormAccount-label">Group object class</label></div>
<div class="FormAccount-rowData"><%= @ldap_configuration.group_object_class %></div>
</div>
@@ -0,0 +1,51 @@
<%#
# @param title [String] (local) page html title to be appended to organization name
# @params settings_body [String] (yielded content) HTML content for the main section
%>
<% content_for(:page_title) do %>
<%= current_user.organization.name %> <%= title %> |
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var username = "<%= current_user.username %>";
var organization_data = {
base_url: "<%= CartoDB.url(self, 'create_organization_user', user: current_user) %>", // HACK!!!
id: "<%= current_user.organization.id %>",
quota_in_bytes: <%= current_user.organization.quota_in_bytes %>,
seats: <%= current_user.organization.seats %>,
viewer_seats: <%= current_user.organization.viewer_seats %>,
assigned_seats: <%= current_user.organization.assigned_seats %>,
assigned_viewer_seats: <%= current_user.organization.assigned_viewer_seats %>,
owner: { id: "<%= current_user.organization.owner.id %>" },
admins: <%= current_user.organization.users.select(&:org_admin).map { |u| { id: u.id } }.to_json.html_safe %>,
signup_enabled: <%= current_user.organization.auth_username_password_enabled || current_user.organization.auth_google_enabled %>
};
var config = <%= safe_js_object frontend_config %>;
var authenticity_token = "<%= form_authenticity_token %>";
var user_data = <%= safe_js_object current_user.data.to_json.html_safe %>;
<% if @avatar_valid_extensions %>
var avatar_valid_extensions = <%= raw @avatar_valid_extensions %>;
<% end %>
var mobile_enabled = "<%= current_user.mobile_sdk_enabled? %>";
var organization_notifications = <%= safe_js_object @organization_notifications.to_json %>;
</script>
<%= javascript_include_tag 'common', 'common_vendor', 'organization' %>
<% end %>
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'organization.css', :media => 'all' %>
<% end %>
<%= render :partial => 'shared/flash_message' %>
<div class="CDB-Text FormAccount-Section u-inner">
<%= render partial: 'admin/shared/pages_subheader' %>
<div class="FormAccount-Content CDB-Text">
<%= render partial: 'admin/shared/org_subheader' %>
<%= yield :settings_body %>
</div>
</div>
<%= render 'admin/shared/new_private_footer' %>
+131
View File
@@ -0,0 +1,131 @@
<% content_for :settings_body do %>
<div class="FormAccount-container">
<% if @ldap_configuration %>
<%= render :partial => 'admin/organizations/ldap_configuration' %>
<% else %>
<%= form_for @organization, url: CartoDB.url(self, 'organization_auth_update', user: current_user), multipart: true do |f| %>
<%= csrf_meta_tags %>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Whitelisted email domains</label>
</div>
<div class="FormAccount-rowData">
<div class="FormAccount-tags js-domains">
<ul class="CDB-Text CDB-Size-medium FormAccount-tagsList js-domainsList">
<span class= "CDB-Text CDB-Size-small u-altTextColor FormAccount-tagsList--placeholder js-placeholder">Only valid domains, wildcard (*) accepted (ex. *.carto.com)</span>
</ul>
</div>
<%= f.hidden_field :whitelisted_email_domains, :value => "#{ @organization[:whitelisted_email_domains].join(',') if !@organization[:whitelisted_email_domains].blank? }", :class => "js-whitelist CDB-InputText CDB-Text", :placeholder => "Only valid domains, wildcard (*) accepted (ex. *.carto.com)" %>
<div class="u-flex u-lSpace--xl">
<% if @organization.errors[:whitelisted_email_domains].present? %>
<p class="CDB-Text FormAccount-rowInfoText FormAccount-rowInfoText--error u-tSpace"><%= @organization.errors[:whitelisted_email_domains].first%></p>
<% end %>
<p class="CDB-Text CDB-Size-small u-altTextColor">If empty, login and signup pages will be disabled</p>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Username / password</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :auth_username_password_enabled, :id => "auth_username_password_enabled" %>
<%= label_tag(:auth_username_password_enabled, '') %>
</div>
<div class="u-flex u-lSpace--xl">
<p class="CDB-Text CDB-Size-small u-altTextColor">Allow users to signup with their own username & email submission</p>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Google Apps Login</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :auth_google_enabled, :id => "auth_google_enabled" %>
<%= label_tag(:auth_google_enabled, '') %>
</div>
<div class="u-flex u-lSpace--xl">
<p class="CDB-Text CDB-Size-small u-altTextColor">Allow users to signup with their own Google domain account</p>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">GitHub Login</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :auth_github_enabled, :id => "auth_github_enabled" %>
<%= label_tag(:auth_github_enabled, '') %>
</div>
<div class="u-flex u-lSpace--xl">
<p class="CDB-Text CDB-Size-small u-altTextColor">Allow users to signup with their own GitHub account</p>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Strong Passwords</label>
</div>
<div class="FormAccount-rowData">
<div class="Toggler">
<%= f.check_box :strong_passwords_enabled, :id => "strong_passwords_enabled" %>
<%= label_tag(:strong_passwords_enabled, '') %>
</div>
<div class="u-flex u-lSpace--xl">
<p class="CDB-Text CDB-Size-small u-altTextColor">Passwords must contain 8 characters, and require a combination of letters, numbers, and/or special characters.</p>
</div>
</div>
</div>
<div class="FormAccount-row">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Password Expiration</label>
</div>
<div class="FormAccount-rowData">
<div class="FormAccount-inputSuffix">
<%= f.text_field :password_expiration_in_d,
:type => "number",
:class => "CDB-InputText CDB-Text FormAccount-input FormAccount-input--number",
:placeholder => "#{@organization.default_password_expiration_in_d || 180}", :min => 1, :max => 365,
:value => "#{@organization.password_expiration_in_d}",
:disabled => @organization.password_expiration_in_d ? false : true %>
<label class="CDB-Text CDB-Size-small u-altTextColor">days</label>
</div>
<div class="CDB-Legend u-upperCase CDB-Text is-semibold CDB-Size-small u-lSpace--xxl">
<div class="u-flex u-alignCenter">
<div class="u-iBlock u-rSpace--m">
<input class="CDB-Checkbox js-input"
type="checkbox"
id="unlimited_password_expiration"
<%= !@organization.password_expiration_in_d ? 'checked' : '' %> />
<span class="u-iBlock CDB-Checkbox-face"></span>
</div>
<label for="unlimited_password_expiration">Unlimited</label>
</div>
</div>
</div>
</div>
<div class="FormAccount-footer">
<p class="FormAccount-footerText"></p>
<button type="submit" class="CDB-Button CDB-Button--primary js-save">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">Save changes</span>
</button>
</div>
<% end %>
<% end %>
</div>
<% end %>
<%= render template: 'admin/organizations/_organization_settings', locals: { title: 'auth settings' } %>
@@ -0,0 +1,6 @@
<% content_for :settings_body do %>
<div class="js-groups-content">
<%= render partial: 'admin/shared/loading', locals: { title: 'Loading assets' } %>
</div>
<% end %>
<%= render template: 'admin/organizations/_organization_settings', locals: { title: 'groups' } %>
@@ -0,0 +1,102 @@
<% content_for :settings_body do %>
<div class="FormAccount-container js-OrganizationNotification">
<%= form_for @notification, url: CartoDB.url(self, 'new_organization_notification_admin', user: current_user) do |f| %>
<%= csrf_meta_tags %>
<div class="FormAccount-row FormAccount-row--smallMarginBottom">
<div class="FormAccount-rowLabel">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Notification Description</label>
</div>
<div class="FormAccount-rowData">
<%= f.text_area :body, :class => "CDB-Textarea CDB-Text FormAccount-textarea FormAccount-input FormAccount-input--totalwidth OrganizationNotifications-textarea js-textarea" %>
<div class="Md-container" data-title="*Italic*, **Bold** and [Link](http://url.com) supported">
<span class="Md-icon u-rSpace--m">
<svg width="16px" height="8px" viewBox="0 0 16 8" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="Md-buttonInner">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill-rule="nonzero" fill="#FFFFFF">
<polygon points="0 7.01999998 0 0 2.06470588 0 4.12941175 2.58088235 6.19411763 0 8.25882351 0 8.25882351 7.01999998 6.19411763 7.01999998 6.19411763 2.99382352 4.12941175 5.57470587 2.06470588 2.99382352 2.06470588 7.01999998"></polygon>
<polygon points="12.9044117 7.01999998 9.80735291 3.61323528 11.8720588 3.61323528 11.8720588 0 13.9367647 0 13.9367647 3.61323528 16.0014705 3.61323528"></polygon>
</g>
</g>
</svg>
</span>
<p class="Md-text CDB-Text CDB-Size-small u-altTextColor">Supported markup</p>
</div>
</div>
<div class="FormAccount-rowInfo">
<p class="FormAccount-rowInfoText"></p>
</div>
</div>
<div class="OrganizationNotification-submissionRow js-update">
<div class="FormAccount-rowData">
<div class="CDB-Text CDB-Size-medium u-rSpace--xl">
<label class="CDB-Text CDB-Size-medium is-semibold u-mainTextColor">Send to:</label>
<% Carto::Notification::RECIPIENTS.each do |recipient| %>
<input class="CDB-Radio u-lSpace--xl" type="radio" name="carto_notification[recipients]" value="<%= recipient %>" <%= recipient == @notification.recipients ? 'checked' : '' %> required="true">
<span class="u-iBlock CDB-Radio-face u-lSpace--xl"></span>
<label class="u-iBlock u-lSpace CDB-Text CDB-Size-medium u-secondaryTextColor is-semibold"><%= recipient.capitalize %></label>
<% end %>
</div>
</div>
<div class="FormAccount-rowData js-send">
<p class="Md-counter CDB-Text CDB-Size-medium u-secondaryTextColor u-rSpace--xl">140</p>
<button type="submit" class="OrganizationNotifications-button CDB-Button CDB-Button--primary is-disabled js-save">
<div class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase u-flex">Send</div>
</button>
</div>
</div>
<% end %>
<% if @notifications.size > 0 %>
<div class="OrganizationNotifications">
<div class="FormAccount-title">
<p class="FormAccount-titleText">
Past Notifications
<span class="FormAccount-subtitleText">
(stores up to 12 most recent notifications)
</span>
</p>
</div>
<span class="FormAccount-separator"></span>
<ul class="NotificationsList">
<% @notifications.each do |notification| %>
<li class="NotificationsList-item js-NotificationsList-item">
<div class="NotificationsList-itemCategory NotificationsList-itemCategory--<%= notification.icon %>">
</div>
<div class="NotificationsList-itemInfo">
<div class="NotificationsList-itemPrimaryInfo">
<div class="NotificationsList-itemTitle CDB-Text CDB-Size-large u-mainTextColor js-html_body" data-body="<%= notification.body %>">
<%= raw notification.html_body %>
</div>
<div class="NotificationsList-itemDescription">
<p class="CDB-Text CDB-Size-medium u-altTextColor"><abbr title="<%= notification.created_at %>" class="u-rSpace--xl"><%= notification.created_at.strftime("%d/%m/%Y") %></abbr> User type: <span class="js-recipients" data-recipients="<%= notification.recipients %>"><%= notification.recipients.capitalize %></span></p>
</div>
</div>
<div class="NotificationsList-itemSecondaryInfo">
<div class="NotificationsList-itemMeta CDB-Text CDB-Size-small">
<button class="FormAccount-link NotificationsList-itemLink js-resend">Resend</button>
</div>
<div class="NotificationsList-itemMeta CDB-Text CDB-Size-small">
<button class="FormAccount-link NotificationsList-itemLink NotificationsList-itemLink--remove js-remove" data-id="<%= notification.id %>">Remove for all users</button>
</div>
</div>
</div>
</li>
<% end %>
</ul>
</div>
<% end %>
</div>
<% end %>
<%= render template: 'admin/organizations/_organization_settings', locals: { title: 'notifications' } %>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,45 @@
<% content_for(:page_title) do %>
<%= current_user.organization.name %> |
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var username = "<%= current_user.username %>";
var type = "oauth";
var config = <%= safe_js_object frontend_config %>;
var organization_data = {
base_url: "<%= CartoDB.url(self, 'create_organization_user', user: current_user) %>", // HACK!!!
id: "<%= current_user.organization.id %>",
quota_in_bytes: <%= current_user.organization.quota_in_bytes %>,
seats: <%= current_user.organization.seats %>,
viewer_seats: <%= current_user.organization.viewer_seats %>,
assigned_seats: <%= current_user.organization.assigned_seats %>,
assigned_viewer_seats: <%= current_user.organization.assigned_viewer_seats %>,
owner: { id: "<%= current_user.organization.owner.id %>" },
admins: <%= current_user.organization.users.select(&:org_admin).map { |u| { id: u.id } }.to_json.html_safe %>,
signup_enabled: <%= current_user.organization.auth_username_password_enabled || current_user.organization.auth_google_enabled %>
};
var user_data = <%= safe_js_object current_user.data.to_json.html_safe %>;
var upgrade_url = "<%= current_user.upgrade_url(request.protocol) %>";
var organization_notifications = <%= safe_js_object @organization_notifications.to_json %>;
</script>
<%= javascript_include_tag 'common', 'common_vendor', 'organization' %>
<% end %>
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'organization.css', :media => 'all' %>
<% end %>
<%= render :partial => 'shared/flash_message' %>
<div class="FormAccount-Section u-inner">
<%= render :partial => 'admin/shared/pages_subheader' %>
<div class="FormAccount-Content">
<%= render :partial => 'admin/shared/org_subheader' %>
<div class="FormAccount-container FormAccount-container--short">
<div class="FormAccount js-orgUsersList"></div>
</div>
</div>
</div>
<%= render 'admin/shared/new_private_footer' %>
@@ -0,0 +1,54 @@
<%= content_for(:title) do %>CARTO · Datasets by <%= @name %><% end %>
<%= content_for(:description) do %><%= @page_description %><% end %>
<div class="CDB-Text PublicBody-content">
<% if @datasets.size == 0 %>
<%= render 'admin/shared/no_results', is_maps: false, alt_url: CartoDB.url(self, 'public_maps_home') %>
<% else %>
<ul class="MapsList">
<% @datasets.each do |vis| %>
<li class="MapsList-item">
<div class="MapCard MapCard--squared MapCard--borderless" data-vis-id="<%= vis[:id] %>" data-vis-owner-name="<%= vis[:owner].username %>">
<a href="<%= CartoDB.url(self, 'public_table', params: { id: vis[:title] }, user: vis[:owner]) %>" class="MapCard-header js-header">
<div class="MapCard-loader"></div>
</a>
<div class="MapCard-content">
<div class="MapCard-contentFooter MapCard-contentFooter--with-icon">
<div class="MapCard-contentFooterIcon">
<div class="DatasetsList-itemCategory is--<%= vis[:geometry_type] %>Dataset"></div>
</div>
<div class="MapCard-contentFooterDetails u-ellipsLongText">
<div class="MapCard-contentFooterTitle">
<h3 class="MapCard-title DefaultTitle CDB-Text is-semibold CDB-Size-large">
<a href="<%= CartoDB.url(self, 'public_table', params: { id: vis[:title] }, user: vis[:owner]) %>" class="DefaultTitle-link u-ellipsLongText" title="<%= vis[:title] %>"><%= vis[:title] %></a>
</h3>
</div>
<div class="MapCard-contentFooterIcons CDB-Size-medium u-altTextColor">
<div class="MapCard-contentFooterDetails--left">
<div class="MapCard-contentFooterTimeDiff DefaultTimeDiff CDB-Text CDB-Size-medium u-altTextColor">
<i class="CDB-IconFont CDB-IconFont-clock DefaultTimeDiff-icon"></i>
<%= time_ago_in_words(vis[:updated_at]) %> ago
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
<% end %>
<% ((3 - @datasets.size + 3) % 3).times.each do %>
<li class="MapsList-item MapsList-item--fake">
<div class="MapCard MapCard--squared MapCard--borderless">
<div class="MapCard-header MapCard-header--fake"></div>
<div class="MapCard-content"></div>
</div>
</li>
<% end %>
</ul>
<% end %>
</div>
<%= render 'admin/pages/shared/pagination' %>
@@ -0,0 +1,26 @@
<%= content_for(:title) do %>CARTO · Maps by <%= @name %><% end %>
<%= content_for(:description) do %><%= @page_description %><% end %>
<div class="CDB-Text PublicBody-content">
<% if @visualizations.size == 0 %>
<%= render 'admin/shared/no_results', is_maps: true, alt_url: CartoDB.url(self, 'public_datasets_home') %>
<% else %>
<ul class="MapsList">
<% @visualizations.each do |vis| %>
<%= render 'shared/mapcard', vis: vis %>
<% end %>
<%# at most 3 cards per line, visbility is handled by CSS depending on viewport size %>
<% ((3 - @visualizations.size + 3) % 3).times.each do %>
<li class="MapsList-item MapsList-item--fake">
<div class="MapCard MapCard--squared MapCard--borderless">
<div class="MapCard-header MapCard-header--fake"></div>
<div class="MapCard-content"></div>
</div>
</li>
<% end %>
</ul>
<% end %>
</div>
<%= render 'admin/pages/shared/pagination' %>
@@ -0,0 +1,45 @@
<li class="MapsList-item">
<div class="MapCard" data-vis-id="<%= vis[:id] %>" data-vis-owner-name="<%= vis[:owner][:username] %>">
<a href="<%= CartoDB.url(self, 'public_visualizations_public_map', params: { id: vis[:id] }, user: vis[:owner]) %>" class="MapCard-header js-header">
<div class="MapCard-loader"></div>
</a>
<div class="MapCard-content">
<div class="MapCard-contentBody">
<div class="MapCard-contentBodyRow MapCard-contentBodyRow--flex">
<h3 class="MapCard-title DefaultTitle CDB-Text is-semibold CDB-Size-large">
<a href="<%= CartoDB.url(self, 'public_visualizations_public_map', params: { id: vis[:id] }, user: vis[:owner]) %>" class="DefaultTitle-link u-ellipsLongText" title="<%= vis[:title] %>"><%= vis[:title] %></a>
</h3>
</div>
<div class="MapCard-contentBodyRow MapCard-contentBodyRow--flex">
<% if vis[:description].present? %>
<div class="MapCard-desc">
<div class="DefaultDescription" title="<%= markdown_html_clean(vis[:description]) %>"><%= raw markdown_html_safe(vis[:description]) %></div>
</div>
<% else %>
<span class="NoResults"></span>
<% end %>
</div>
<div class="MapCard-tags">
<div class="DefaultTags MapCard-contentBodyRow">
<% if vis[:tags].size > 0 %>
<%# Keep on one line to avoid unwanted spaces %>
<% formatted_tags(vis[:tags]) do |tag| %><a class="CDB-Tag CDB-Text CDB-Size-small u-upperCase DefaultTags-item js-tag-link" href="<%= CartoDB.url(self, 'public_tag', params: { tag: tag }, user: vis[:owner]) %>"><%= tag %></a><% end %>
<% end %>
</div>
</div>
</div>
<div class="MapCard-contentFooter CDB-Size-medium u-altTextColor">
<div class="MapCard-contentFooterDetails--left">
<div class="MapCard-contentFooterTimeDiff DefaultTimeDiff CDB-Text CDB-Size-medium u-altTextColor">
<i class="CDB-IconFont CDB-IconFont-clock DefaultTimeDiff-icon"></i>
<%= time_ago_in_words(vis[:updated_at]) %> ago
</div>
</div>
</div>
</div>
</div>
</li>
@@ -0,0 +1,18 @@
<div class="ContentFooter">
<div class="u-inner ContentFooter-inner ContentFooter-inner--paginationOnly">
<div class="js-content-footer"></div>
</div>
</div>
<% content_for(:js) do %>
<script type="text/javascript">
var paginationModelAttrs = {
current_page: <%= @current_page %>,
total_count: <%= @total_count %>,
per_page: <%= @per_page %>,
url_to: function(page) {
return '<%= @numbered_page_url %>'.replace('<%= @page_number_placeholder %>', page);
}
}
</script>
<% end %>
@@ -0,0 +1,28 @@
<% if @tags.size > 0 %>
<ul class="tags">
<li><strong>Browse by tag</strong></li>
<% @tags.last(10).reverse.each_with_index do |tag, i| %>
<li<%= " class='#{i == 0 ? "first" : "last" }'" if i == 0 || i == @tags.size - 1 %>>
<% if params[:tag] && params[:tag] == tag %>
<% if action_name == 'datasets' %>
<%= tag.capitalize.truncate(40) %> <%= link_to "x", "/datasets", { :class => "close" } %>
<% else %>
<%= link_to "x", "/", { :class => "close" } %>
<h3><%= tag.capitalize.truncate(40) %></h3>
<% end %>
<% else %>
<% if action_name == 'datasets' %>
<h3><%= link_to tag.capitalize.truncate(40), CartoDB.url(self, 'public_datasets_tag', params: { tag: tag }), :rel => "tag" %></h3>
<% else %>
<h3><%= link_to tag.capitalize.truncate(40), CartoDB.url(self, 'public_tag', params: { tag: tag }), :rel => "tag" %></h3>
<% end %>
<% end %>
</li>
<% end %>
</ul>
<% end %>
@@ -0,0 +1,9 @@
# app/views/sitemaps/index.xml.builder
xml.urlset(xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9") do
@urls.each do |path|
xml.url do
xml.loc path[:loc]
xml.lastmod path[:lastfreq]
end
end
end
+60
View File
@@ -0,0 +1,60 @@
<%= content_for(:title) do %>CARTO &middot; <%= @name %> public feed<% end %>
<%= content_for(:description) do %><%= @page_description %><% end %>
<div class="CDB-Text PublicBody-content PublicBody--grey">
<div class="PublicUserProfile">
<div class="PublicUserProfile-profile">
<div class="PublicUserProfile-bio">
<h2 class="CDB-Size-huge PublicUserProfile-name u-breakLongWords"><%= @name %></h2>
<% unless @viewed_user.description.nil? || @tables_num == 0 %>
<p class="PublicUserProfile-description"><%= @viewed_user.description %></p>
<% end %>
</div>
<ul class="PublicUserProfile-details">
<% unless @viewed_user.twitter_username.blank? || @tables_num == 0 %>
<li class="PublicUserProfile-detail">
<i class="CDB-IconFont CDB-IconFont-twitter CDB-IconFont--withLabel"></i>
<a href="http://twitter.com/<%= @viewed_user.twitter_username %>"><%= @viewed_user.twitter_username %></a>
</li>
<% end %>
<% unless @viewed_user.website.blank? || @tables_num == 0 %>
<li class="PublicUserProfile-detail">
<i class="CDB-IconFont CDB-IconFont-anchor CDB-IconFont--withLabel"></i>
<a href="<%= @website %>"><%= @website_clean %></a>
</li>
<% end %>
<% if @viewed_user.has_organization? %>
<li class="PublicUserProfile-detail">
<i class="CDB-IconFont CDB-IconFont-attache CDB-IconFont--withLabel"></i>
<%= @viewed_user.organization.name %>
</li>
<% end %>
<% if @viewed_user.available_for_hire %>
<li class="PublicUserProfile-detail">
<i class="CDB-IconFont CDB-IconFont-email CDB-IconFont--withLabel"></i>
<a href="mailto:<%= @viewed_user.email %>"><%= @viewed_user.email %></a>
</li>
<% end %>
<% unless @viewed_user.location.blank? %>
<li class="PublicUserProfile-detail">
<i class="CDB-IconFont CDB-IconFont-pin CDB-IconFont--withLabel"></i>
<%= @viewed_user.location %>
</li>
<% end %>
<li class="PublicUserProfile-detail">
<i class="CDB-IconFont CDB-IconFont-calendar CDB-IconFont--withLabel"></i>
Member since <%= @viewed_user.created_at.strftime("%B %Y") %>
</li>
</ul>
</div>
<div class="Feed js-feed"></div>
</div>
</div>
@@ -0,0 +1,42 @@
<%- if Cartodb::Central.sync_data_with_cartodb_central? && current_user.mobile_sdk_enabled? %>
<div class="Filters is-relative js-org-subheader Filters__margin-fix">
<div class="Filters-inner">
<span class="Filters-separator"></span>
<div class="Filters-row">
<ul class="Filters-group">
<li class="Filters-typeItem">
<a href="<%= CartoDB.url(self, 'api_key_credentials', user: current_user) %>" class=" CDB-Text CDB-Size-medium Filters-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/client_applications_api_key" %>">
API Keys
</a>
</li>
<li class="Filters-typeItem">
<a href="<%= CartoDB.base_url_from_user(current_user) %>/dashboard/oauth_apps" class="CDB-Text CDB-Size-medium Filters-typeLink">
Oauth apps
</a>
</li>
<li class="Filters-typeItem">
<a href="<%= CartoDB.url(self, 'mobile_apps', user: current_user) %>" class="CDB-Text CDB-Size-medium Filters-typeLink <%= 'is-selected' if "#{params[:controller]}" == "carto/admin/mobile_apps" %>">
Mobile apps
</a>
</li>
</ul>
<% if "#{params[:controller]}_#{params[:action]}" == "carto/admin/mobile_apps_index" %>
<ul class="Filters-group">
<a href="<%= CartoDB.url(self, 'new_mobile_app', user: current_user) %>" class="CDB-Button CDB-Button--primary">
<span class="CDB-Button-Text CDB-Text is-semibold CDB-Size-small u-upperCase">New application</span>
</a>
</ul>
<% end %>
</div>
</div>
</div>
<% else %>
<div class="FormAccount-title">
<p class="FormAccount-titleText">访问您的私人数据的最简单方法</p>
</div>
<% end %>
@@ -0,0 +1,53 @@
<div class="Header Header--tall CDB-Text Header--dark Header--datalibrary js-Header--datalibrary" id="header">
<div class="Header-inner u-inner">
<div class="Header-navigation">
<ul class="Header-navigationList">
<li class="js-logo">
<a href="<%= cartodb_com_hosted? ? CartoDB.url(self, 'root') : "https://carto.com" %>">
<span class="Logo">
<img src="<%= image_path "layout/carto-logo.svg" %>" alt="carto">
</span>
</a>
</li>
<% unless cartodb_com_hosted? %>
<li class="Header-navigationItem js-user-tour u-hideOnTablet">
<a href="https://carto.com/builder/" class="Header-navigationLink">Builder</a>
</li>
<li class="Header-navigationItem js-user-tour u-hideOnTablet">
<a href="https://carto.com/engine/" class="Header-navigationLink">Engine</a>
</li>
<li class="Header-navigationItem js-user-industries u-hideOnTablet">
<a href="#/industries" class="Header-navigationLink js-dropdown-target">Solutions <i class="Header-darrow CDB-IconFont CDB-IconFont-caretDown"></i></a>
</li>
<li class="Header-navigationItem u-hideOnTablet">
<a href="https://carto.com/pricing/" class="Header-navigationLink">Pricing</a>
</li>
<li class="Header-navigationItem u-hideOnTablet">
<a href="https://carto.com/blog/" class="Header-navigationLink">Blog</a>
</li>
<% end %>
</ul>
</div>
<div class="Header-settings">
<ul class="Header-settingsList js-user-settings">
<li class="Header-settingsItem js-login">
<a href="<%= CartoDB.url(self, 'login') %>" class="Header-settingsLink Header-settingsLink Header-settingsLink--public">Login</a>
</li>
<% unless cartodb_com_hosted? %>
<li class="Header-settingsItem">
<a href="https://carto.com/signup" class="PublicButton PublicButton--sMedium PublicButton--cWhite is-hover PublicButton--public">
<span>Sign up</span>
</a>
</li>
<% end %>
</ul>
</div>
</div>
</div>
+24
View File
@@ -0,0 +1,24 @@
<% light = local_assigns.fetch(:light, false) %>
<% footer_margin = local_assigns.fetch(:footer_margin, true) %>
<div class="CDB-Text CDB-FontSize-medium <%= 'u-tSpace-xl' if footer_margin %> Footer <%= 'Footer--light' if light %>">
<div class="u-inner Footer-inner">
<ul class="Footer-list Footer-list--primary">
<% unless cartodb_com_hosted? %>
<li class="Footer-listItem CDB-Text CDB-Size-medium"><a href="https://carto.com/learn/guides/">Guides</a></li>
<li class="Footer-listItem CDB-Text CDB-Size-medium"><a href="https://carto.com/developers">Developers</a></li>
<% end %>
<% unless cartodb_onpremise_version.blank? %>
<li class="Footer-listItem CDB-Text CDB-Size-medium">Version: <%= cartodb_onpremise_version %></li>
<% end %>
</ul>
<ul class="Footer-list Footer-list--secondary">
<% unless cartodb_com_hosted? %>
<li class="Footer-listItem CDB-Text CDB-Size-medium"><a href="mailto:support@carto.com">Support</a></li>
<% else %>
<li class="Footer-listItem CDB-Text CDB-Size-medium"><a href="mailto:onpremise-support@carto.com">Support</a></li>
<% end %>
<li class="Footer-listItem CDB-Text CDB-Size-medium"><a href="mailto:contact@carto.com">Contact</a></li>
</ul>
</div>
</div>
+15
View File
@@ -0,0 +1,15 @@
<%
intercom_app_id = Cartodb.get_config(:intercom, 'app_id')
if intercom_app_id.present? && current_user && (current_user.has_feature_flag?('intercom'))
%>
<script>
window.intercomSettings = {
app_id: "<%= intercom_app_id %>",
email: "<%= current_user.email %>"
};
</script>
<script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/<%= intercom_app_id %>';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>
<%
end
%>
+5
View File
@@ -0,0 +1,5 @@
<div class="IntermediateInfo">
<div class="Spinner"></div>
<h4 class="CDB-Text CDB-Size-large u-mainTextColor u-secondaryTextColor u-bSpace--m u-tSpace-xl"><%= title %></h4>
<div class="CDB-Text CDB-Size-medium u-altTextColor">&nbsp;</div>
</div>
@@ -0,0 +1,7 @@
<div id="footer">
<div class="js-footer"></div>
</div>
<% content_for :css do %>
<%= stylesheet_link_tag 'footer.css', :media => 'all' %>
<% end %>
@@ -0,0 +1,8 @@
<div id="header">
<nav class="navbar-placeholder">
<div class="navbar-placeholder-logo">
<%= image_tag ("imagotype.svg") %>
</div>
</nav>
</div>
<%= stylesheet_link_tag 'header.css', :media => 'all' %>
@@ -0,0 +1,12 @@
<div class="IntermediateInfo">
<div class="LayoutIcon">
<i class="CDB-IconFont CDB-IconFont-map"></i>
</div>
<% if @total_count > 0 %>
<h3 class="CDB-Text CDB-Size-large u-mainTextColor u-secondaryTextColor u-bSpace--m u-tSpace-xl"><%= @name %> doesn't have any items on this page</h3>
<p class="CDB-Text CDB-Size-medium u-altTextColor">Try the <%= link_to 'first page', @first_page_url %> instead</p>
<% else %>
<h3 class="CDB-Text CDB-Size-large u-mainTextColor u-secondaryTextColor u-bSpace--m u-tSpace-xl"><%= @name %> doesn't have any public <%= @content_type === 'maps' ? 'maps' : 'datasets' %> yet</h3>
<p class="CDB-Text CDB-Size-medium u-altTextColor">But maybe they have some very interesting <%= link_to @content_type === 'maps' ? 'datasets' : 'maps', alt_url %></p>
<% end %>
</div>
@@ -0,0 +1,12 @@
<header class="cartodb-public-header">
<div class="inner">
<h1><%= link_to "CARTO", "https://carto.com", :id => "the_logo", :class => "logo" %></h1>
<ul class="options">
<li><a href="https://carto.com/learn/guides" class="guides">Guides</a><li>
<% unless cartodb_com_hosted? %>
<li><a class="signup" href="https://carto.com/signup">Sign up</a><li>
<% end %>
<li><a href="https://carto.com/login" class="border login">Login</a></li>
</ul>
</div>
</header>
@@ -0,0 +1,41 @@
<div class="Filters is-relative js-org-subheader Filters__margin-fix">
<div class="Filters-inner">
<span class="Filters-separator"></span>
<div class="Filters-row">
<ul class="Filters-group CDB-Text CDB-Size-medium">
<% if current_user.organization_owner? %>
<li class="Filters-typeItem">
<a href="<%= current_user_url('organization_settings') %>" class="Filters-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/organizations_settings" %>">
Organization profile
</a>
</li>
<li class="Filters-typeItem">
<a href="<%= current_user_url('organization_auth') %>" class="Filters-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/organizations_auth" %>">
Auth settings
</a>
</li>
<% end %>
<li class="Filters-typeItem">
<a href="<%= current_user_url('organization_users') %>" class="Filters-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/organizations_show" %>">
<%= current_user.organization.users.count %>/<%= current_user.organization.total_seats %> users
</a>
</li>
<li class="Filters-typeItem">
<a href="<%= current_user_url('organization_groups') %>" class="Filters-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/organizations_groups" %>">
Groups
</a>
</li>
<li class="Filters-typeItem">
<a href="<%= current_user_url('organization_notifications_admin') %>" class="Filters-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/organizations_notifications" || "#{params[:controller]}_#{params[:action]}" == "admin/organizations_new_notification" %>">
Notifications
</a>
</li>
<% if show_billing %>
<li class="Filters-typeItem">
<a href="<%= current_user.plan_url(request.protocol) %>" class="Filters-typeLink">Billing</a>
</li>
<% end %>
</ul>
</div>
</div>
</div>
@@ -0,0 +1,18 @@
<div class="SideMenu CDB-Text CDB-Size-medium">
<div class="SideMenu-type">
<ul class="SideMenu-list">
<li class="SideMenu-typeItem"><a href="<%= CartoDB.url(self, 'profile_user', user: current_user) %>" class="SideMenu-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/users_profile" %>">个人资料</a></li>
<li class="SideMenu-typeItem"><a href="<%= CartoDB.url(self, 'account_user', user: current_user) %>" class="SideMenu-typeLink <%= 'is-selected' if "#{params[:controller]}_#{params[:action]}" == "admin/users_account" %>">账户</a></li>
<li class="SideMenu-typeItem"><a href="<%= CartoDB.url(self, 'connected_apps_user', user: current_user) %>" class="SideMenu-typeLink">APP应用</a></li>
<% if current_user.organization_admin? %>
<li class="SideMenu-typeItem"><a href="<%= CartoDB.url(self, current_user.organization_owner? ? 'organization_settings' : 'organization', user: current_user) %>" class="SideMenu-typeLink <%= 'is-selected' if ["admin/organizations", "admin/organization", "admin/organization_users"].include?("#{params[:controller]}") %>" class="SideMenu-typeLink">组织设置</a></li>
<% end %>
<% pages_subheader_instance.links(self).each do |link| %>
<li class="SideMenu-typeItem"><a href="<%= link.path %>" class="SideMenu-typeLink <%= 'is-selected' if [link.controller].include?("#{params[:controller]}") %>" class="SideMenu-typeLink"><%= link.text %></a></li>
<% end %>
<span class="SideMenu-separator"></span>
<li class="SideMenu-typeItem"><a href="<%= CartoDB.url(self, 'api_key_credentials', user: current_user) %>" class="SideMenu-typeLink <%= 'is-selected' if "#{params[:controller]}" == "admin/client_applications" || "#{params[:controller]}" == "carto/admin/mobile_apps" %>">开发设置</a></li>
</ul>
</div>
</div>
@@ -0,0 +1,56 @@
<% breadcrumb = local_assigns.fetch(:breadcrumb, true) %>
<div class="Header CDB-Text" id="header">
<div class="u-inner Header-inner">
<div class="Header-navigation">
<ul class="Header-navigationList">
<li class="js-logo">
<a href="<%= CartoDB.url(self, 'root') %>">
<span class="Logo">
<img src="<%= image_path "layout/carto-logo.svg" %>" alt="carto">
</span>
</a>
</li>
<li>
<ul class="Header-navigationBreadcrumb">
<% if current_user.has_organization? %>
<li class="Header-navigationBreadcrumbItem CDB-Text CDB-Size-large"><p class="Header-navigationBreadcrumbParagraph"><%= current_user.organization.name %></p> /</li>
<% end %>
<% if breadcrumb %>
<li class="Header-navigationBreadcrumbItem CDB-Text CDB-Size-large">
<% if params[:controller] != "admin/visualizations" %>
<p class="Header-navigationBreadcrumbParagraph"><%= link_to current_user.name_or_username, CartoDB.url(self, 'dashboard', user: current_user), :class => "Header-navigationBreadcrumbLink" %></p> /
<% else %>
<p class="Header-navigationBreadcrumbParagraph"><%= current_user.name_or_username %></p> /
<% end %>
</li>
<li class="Header-navigationBreadcrumbItem js-breadcrumb-dropdown CDB-Text CDB-Size-large"></li>
<% end %>
</ul>
</li>
</ul>
</div>
<div class="Header-settings">
<ul class="Header-settingsList CDB-Text CDB-Size-medium">
<% unless cartodb_com_hosted? %>
<li class="Header-settingsItem">
<a target="_blank" href="https://carto.com/learn/guides" class="CDB-Text is-semibold Header-settingsLink Header-settingsLink--dashboard">Guides</a>
</li>
<li class="Header-settingsItem">
<a target="_blank" href="https://carto.com/developers" class="CDB-Text is-semibold Header-settingsLink Header-settingsLink--dashboard">Developers</a>
</li>
<% end %>
<li class="Header-settingsItem Header-settingsItemNotifications js-user-notifications">
<button class="UserNotifications">
<i class="UserNotifications-Icon CDB-IconFont CDB-IconFont-Alert"></i>
</button>
</li>
<li class="Header-settingsItem Header-settingsItem--avatar">
<button class="UserAvatar js-settings-dropdown">
<img src="<%= current_user.avatar %>" class='UserAvatar-img UserAvatar-img--medium' />
</button>
</li>
</ul>
</div>
</div>
</div>
@@ -0,0 +1,245 @@
<% light = false if !light.present? %>
<footer id="Footer" class="CDB-Text CDB-FontSize-medium Footer <%= 'Footer--light' if light %> Footer--public u-pr">
<div class="Footer-inner Footer-inner--public">
<div class="u-inner">
<p class="PublicTitle PublicTitle--feature">Subscribe</p>
<h3 class="Title Title--sectionMedium u-vspace--20">Keep up with CARTO announcements</h3>
<div class="Grid u-vspace-l">
<ul class="Grid-inner">
<li class="Grid-cell Grid-cell--col5 Grid-cell--col6--tablet Grid-cell--col12--mobile">
<div class="Newsletter js-Hubspot--newsletter">
<%= insert_hubspot_form() -%>
</div>
</li>
<li class="Grid-cell Grid-cell--col7 Grid-cell--col6--tablet Grid-cell--col12--mobile">
<p class="Footer-social">Or follow us on <a href="https://twitter.com/cartodb" target="_blank" class="Footer-link u-lspace--20">
<i class="FooterIcon FooterIcon--twitter FooterIcon--s14 u-iblock u-malign">
<svg width="18px" height="14px" viewBox="0 0 500 408" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="icons" sketch:type="MSArtboardGroup" transform="translate(-2000.000000, -500.000000)">
<path d="M2157.24789,907.407407 C2099.31782,907.407407 2045.39669,890.381519 2000,861.200045 C2008.02517,862.149901 2016.19116,862.635831 2024.47054,862.635831 C2072.53009,862.635831 2116.76177,846.193059 2151.86912,818.608736 C2106.98087,817.778071 2069.09726,788.042821 2056.04448,747.180689 C2062.30659,748.381761 2068.73331,749.025389 2075.34292,749.025389 C2084.69951,749.025389 2093.76166,747.769306 2102.37024,745.418505 C2055.44095,735.971292 2020.08303,694.401353 2020.08303,644.568769 C2020.08303,644.136016 2020.08303,643.705097 2020.09035,643.276012 C2033.92224,650.979378 2049.73847,655.605799 2066.5551,656.139405 C2039.03032,637.696068 2020.91883,606.215137 2020.91883,570.533203 C2020.91883,551.684619 2025.97754,534.016936 2034.80742,518.82658 C2085.40181,581.051296 2160.98797,621.997778 2246.24346,626.286798 C2244.49504,618.759466 2243.58609,610.909404 2243.58609,602.848467 C2243.58609,546.049664 2289.51681,500 2346.17031,500 C2375.67395,500 2402.33366,512.491152 2421.04686,532.480297 C2444.41274,527.866712 2466.36673,519.307009 2486.1864,507.52183 C2478.52701,531.537776 2462.2627,551.693787 2441.08234,564.42332 C2461.83291,561.936825 2481.6032,556.408225 2500,548.228097 C2486.24675,568.853535 2468.85402,586.96864 2448.81305,601.469526 C2449.01057,605.87957 2449.10933,610.315286 2449.10933,614.77484 C2449.10933,750.68672 2345.93072,907.407407 2157.24789,907.407407" id="icon_14_twitter" sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>
</i>
</a> <a href="https://www.facebook.com/CartoDB" target="_blank" class="Footer-link u-lspace--20">
<i class="FooterIcon FooterIcon--twitter FooterIcon--s14 u-iblock u-malign">
<svg width="14px" height="14px" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="icons" sketch:type="MSArtboardGroup" transform="translate(-2500.000000, -500.000000)">
<path d="M2972.40477,500 L2527.59523,500 C2512.35135,500 2500,512.351345 2500,527.595225 L2500,972.404775 C2500,987.644908 2512.35135,1000 2527.59523,1000 L2767.06483,1000 L2767.06483,806.374441 L2701.906,806.374441 L2701.906,730.913771 L2767.06483,730.913771 L2767.06483,675.264337 C2767.06483,610.682518 2806.50933,575.516872 2864.12021,575.516872 C2891.71544,575.516872 2915.43459,577.571995 2922.34558,578.489962 L2922.34558,645.981176 L2882.38964,645.99991 C2851.05697,645.99991 2844.9909,660.887843 2844.9909,682.735468 L2844.9909,730.913771 L2919.71532,730.913771 L2909.98486,806.374441 L2844.9909,806.374441 L2844.9909,1000 L2972.40477,1000 C2987.64491,1000 3000,987.644908 3000,972.404775 L3000,527.595225 C3000,512.351345 2987.64491,500 2972.40477,500" id="icon_15_facebook" sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>
</i>
</a> <a href="https://www.linkedin.com/company/cartodb" target="_blank" class="Footer-link u-lspace--20">
<i class="FooterIcon FooterIcon--twitter FooterIcon--s14 u-iblock u-malign">
<svg width="14px" height="14px" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="icons" sketch:type="MSArtboardGroup" transform="translate(-3000.000000, -500.000000)">
<path d="M3000,535.816886 C3000,516.041104 3016.54224,500 3036.94908,500 L3463.05091,500 C3483.45709,500 3500,516.041104 3500,535.816886 L3500,964.183113 C3500,983.965579 3483.45709,1000 3463.05091,1000 L3036.94908,1000 C3016.54224,1000 3000,983.965579 3000,964.183113 L3000,535.816886 L3000,535.816886 L3000,535.816886 Z M3141.32261,907.438908 L3141.32261,681.660906 L3065.80209,681.660906 L3065.80209,907.438908 L3141.32261,907.438908 L3141.32261,907.438908 Z M3103.56202,650.834731 C3129.89755,650.834731 3146.28918,633.497514 3146.28918,611.831003 C3145.79838,589.676778 3129.89755,572.820595 3104.06156,572.820595 C3078.22827,572.820595 3061.33775,589.676778 3061.33775,611.831003 C3061.33775,633.497514 3077.72603,650.834731 3103.06986,650.834731 L3103.56067,650.834731 L3103.56202,650.834731 L3103.56202,650.834731 Z M3183.11053,907.438908 L3258.63038,907.438908 L3258.63038,781.354914 C3258.63038,774.607096 3259.12119,767.865958 3261.11534,763.04227 C3266.57474,749.559994 3279.00092,735.596687 3299.86361,735.596687 C3327.19085,735.596687 3338.12241,756.301132 3338.12241,786.652954 L3338.12241,907.438908 L3413.63621,907.438908 L3413.63621,777.981005 C3413.63621,708.632137 3376.37852,676.362864 3326.69197,676.362864 C3285.95089,676.362864 3268.06532,698.991442 3258.12814,714.404528 L3258.6324,714.404528 L3258.6324,681.660906 L3183.11254,681.660906 C3184.10357,702.846383 3183.11254,907.438908 3183.11254,907.438908 L3183.11053,907.438908 L3183.11053,907.438908 Z" id="icon_16_linkedin" sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>
</i>
</a></p>
</li>
</ul>
</div>
<hr class="Sep u-vspace-l u-mobile-hide"></hr>
<div class="u-block--mobile">
<dl class="Footer-column Footer-column--mobile">
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a class="Footer-link" href="https://carto.com/builder/">Builder</a></dd>
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a class="Footer-link" href="https://carto.com/engine/">Engine</a></dd>
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a class="Footer-link" href="https://carto.com/mobile/">Mobile</a></dd>
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a class="Footer-link" href="https://carto.com/location-data-services/">Location Data Services</a></dd>
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a class="Footer-link" href="https://carto.com/data-observatory/">Data Observatory</a></dd>
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a class="Footer-link" href="https://github.com/CartoDB/cartodb">Source Code</a></dd>
<dd class="Footer-item Footer-item--mobile"><i class="FooterIcon FooterIcon--mobile Footer-arrow">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="6px" height="10px" viewBox="0 0 272 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.6.1 (26313) - http://www.bohemiancoding.com/sketch -->
<title>icon_03_caretRight</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icons" transform="translate(-1500.000000, 0.000000)" fill="#ddd">
<path d="M1748.23301,281.69014 L1772,249.999999 L1748.23301,218.309858 L1616.19418,42.2535212 L1584.50485,0 L1500,63.380282 L1531.68932,105.633803 L1639.61495,250.461632 L1531.68932,394.366197 L1500,436.619718 L1584.50485,500 L1616.19418,457.746479 L1748.23301,281.69014 L1748.23301,281.69014 Z" id="icon_03_caretRight"></path>
</g>
</g>
</svg>
</i><a href="https://carto.com/pricing/" class="Footer-link">Pricing</a></dd>
</dl>
</div>
<div class="Grid Footer-columns Footer-columns--noBorder u-mobile-hide">
<ul class="Grid-inner Grid-inner--shortpadding">
<li class="Grid-cell Grid-cell--col2 Grid-cell--col4--tablet Grid-cell--col6--mobile Footer-column">
<dl>
<dt class="Footer-title u-vspace-xs">Product</dt>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/builder/">Builder</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/engine/">Engine</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/mobile/">Mobile</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/location-data-services/">Location Data Services</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/data-observatory/">Data Observatory</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://github.com/CartoDB/cartodb">Source Code</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/pricing/" class="Footer-link">Pricing</a></dd>
</dl>
</li>
<li class="Grid-cell Grid-cell--col2 Grid-cell--col4--tablet Grid-cell--col6--mobile Footer-column">
<dl>
<dt class="Footer-title u-vspace-xs">Solutions</dt>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/banking-and-finance/">Banking & Finance</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/business-intelligence-and-analytics/">BI & Analytics</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/government/">Government</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/real-estate/">Real Estate</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/web-mobile/">Web Development</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/journalism/">Journalism</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/natural-resources/">Natural Resources</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/earth-observation-and-space/">Earth Observation</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/non-profits/">Non-profits</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/solutions/education-and-research/">Education</a></dd>
</dl>
</li>
<li class="Grid-cell Grid-cell--col2 Grid-cell--col4--tablet Grid-cell--col6--mobile Footer-column">
<dl>
<dt class="Footer-title u-vspace-xs">Connectors</dt>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/dropbox/">Dropbox</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/google-drive/">Google Drive</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/twitter-maps/">Twitter Maps</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/mailchimp/">MailChimp</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/excel-data/">Excel Data</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/arcgis/">ArcGIS™</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/satellite-imagery/">Satellite Imagery</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/qlik/">Qlik</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/splunk/">Splunk</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/connectors/alteryx/">Alteryx</a></dd>
</dl>
</li>
<li class="Grid-cell Grid-cell--col2 Grid-cell--col4--tablet Grid-cell--col6--mobile Footer-column">
<dl>
<dt class="Footer-title u-vspace-xs">Discover</dt>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/gallery/">Map Gallery</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/explore">Explore</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/ambassadors/">Ambassadors</a></dd>
</dl>
</li>
<li class="Grid-cell Grid-cell--col2 Grid-cell--col4--tablet Grid-cell--col6--mobile Footer-column">
<dl>
<dt class="Footer-title u-vspace-xs">Learn</dt>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/learn/guides">Guides</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/developers">Developers</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/academy">The Map Academy</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/resources/">Resources Center</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/webinars/">Webinars</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/blog">Blog</a></dd>
</dl>
</li>
<li class="Grid-cell Grid-cell--col2 Grid-cell--col4--tablet Grid-cell--col6--mobile Footer-column">
<dl>
<dt class="Footer-title u-vspace-xs">About us</dt>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/team/">Team</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/jobs/">Jobs</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/press/">Press</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/partners/">Partners</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/attributions">Attributions</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/contributing/">Contributions</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="mailto:sales@carto.com">Contact us</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/request-live-demo/">Request a Live Demo</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/terms/">Terms of Service</a></dd>
<dd class="Footer-item"><a class="Footer-link" href="https://carto.com/legal/">Legal</a></dd>
</dl>
</li>
</ul>
</div>
</div>
</div>
</footer>
@@ -0,0 +1,53 @@
<div class="Header CDB-Text" id="header">
<div class="u-inner Header-inner">
<div class="Header-navigation">
<ul class="Header-navigationList">
<li class="js-logo">
<a href="<%= cartodb_com_hosted? ? CartoDB.url(self, 'root') : "https://carto.com" %>">
<span class="Logo">
<img src="<%= image_path "layout/carto-logo.svg" %>" alt="carto">
</span>
</a>
</li>
<% unless cartodb_com_hosted? %>
<li class="Header-navigationItem js-user-tour u-hideOnTablet">
<a href="https://carto.com/builder/" class="Header-navigationLink">Builder</a>
</li>
<li class="Header-navigationItem js-user-tour u-hideOnTablet">
<a href="https://carto.com/engine/" class="Header-navigationLink">Engine</a>
</li>
<li class="Header-navigationItem js-user-industries u-hideOnTablet">
<a href="#/industries" class="Header-navigationLink js-dropdown-target">Solutions <i class="Header-darrow CDB-IconFont CDB-IconFont-caretDown"></i></a>
</li>
<li class="Header-navigationItem u-hideOnTablet">
<a href="https://carto.com/pricing/" class="Header-navigationLink">Pricing</a>
</li>
<li class="Header-navigationItem u-hideOnTablet">
<a href="https://carto.com/blog/" class="Header-navigationLink">Blog</a>
</li>
<% end %>
</ul>
</div>
<div class="Header-settings">
<ul class="Header-settingsList js-user-settings">
<li class="Header-settingsItem js-login">
<a href="<%= CartoDB.url(self, 'login') %>" class="Header-settingsLink Header-settingsLink Header-settingsLink--public">Login</a>
</li>
<% unless cartodb_com_hosted? %>
<li class="Header-settingsItem">
<a href="https://carto.com/signup" class="PublicButton PublicButton--sMedium PublicButton--cWhite is-hover PublicButton--public">
<span>Sign up</span>
</a>
</li>
<% end %>
</ul>
</div>
</div>
</div>
@@ -0,0 +1,14 @@
<header class="Sessions-header">
<div class="u-inner">
<nav class="Navbar <%= align %>">
<div class="Navbar-header">
<div class="Navbar-title">
<%= render_organization_avatar %>
</div>
<% if !Cartodb.config[:cartodb_com_hosted].present? && @organization.present? %>
<div class="Navbar-text">Not part of <%= @organization.name %>? Go to <a class="Navbar-textLink" href="https://carto.com">carto.com</a></div>
<% end %>
</div>
</nav>
</div>
</header>
@@ -0,0 +1,11 @@
<% if current_user.trial_user? %>
<div class="CDB-Text FlashMessage FlashMessage--main">
<div class="u-inner">
<div class="FlashMessage FlashMessage-info FlashMessage--main u-flex u-justifyCenter u-alignCenter">
<p class="FlashMessage--text"><%= current_user.remaining_trial_days %> days left in your trial.
<a href="<%= current_user.upgrade_url(request.protocol) %>" class="FlashMessage--text">Subscribe now to keep using our platform.</a>
</p>
</div>
</div>
</div>
<% end %>
@@ -0,0 +1,36 @@
<header class="vis">
<div class="inner">
<div class="header_content">
<div class="vis_navigation">
<nav>
<%= link_to "Data view", "#/table", :class => "smaller strong tab selected" %>
<%= link_to "Map view", "#/map", :class => "smaller strong tab" %>
</nav>
</div>
<div class="left">
<ul class="actions">
<li><%= link_to "Back", CartoDB.path(self, 'root'), :class => "back" %></li>
<li><a class="privacy" href="#/visualize"><i class="privacy-status"></i></a></li>
<li><h1><%= link_to @visualization.name, "#/change-title", :class => "title" %></h1></li>
</ul>
<div class="metadata">
<p><a href="#/edit-metadata">Edit metadata…</a></p>
</div>
</div>
<div class="right">
<ul class="options">
<li><%= link_to "Edit", "#/options", :class => "dropdown options" %></li>
<li><a class="rounded share" href="#/visualize"><span>VISUALIZE</span></a></li>
</ul>
</div>
</div>
<div class="sync_status"></div>
<div class="globalerror"></div>
</div>
</header>
+18
View File
@@ -0,0 +1,18 @@
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'new_dashboard', 'new_lockout' %>
<% end %>
<%= content_for(:js) do %>
<script type="text/javascript">
var authenticity_token = "<%= form_authenticity_token %>";
var user_data = <%= safe_js_object @user.data.to_json %>;
var can_change_email = <%= @user.can_change_email? %>;
var payments_url = "<%= @payments_url %>";
// Necessary for Google + actions
var access_token = '';
</script>
<%= javascript_include_tag 'common', 'common_vendor', 'new_lockout' -%>
<% end %>
<div id="root"></div>
@@ -0,0 +1,8 @@
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'new_dashboard', 'maintenance' %>
<% end %>
<%= content_for(:js) do %>
<%= javascript_include_tag 'common', 'common_vendor', 'maintenance' -%>
<% end %>
<div id="root"></div>
@@ -0,0 +1,48 @@
<% require_dependency 'static_maps_url_helper' %>
<%= content_for(:title) do %><%= @visualization.name %><% end %>
<%= content_for(:description) do %><%= @visualization.description.present? ? "#{markdown_html_clean(@visualization.description)}. Map created by #{@name} in CARTO" : "Map created by #{@name} in CARTO" %><% end %>
<%= content_for(:twitter_card) do %><%= Carto::StaticMapsURLHelper.new.url_for_static_map(request, @visualization, 560, 300) %><% end %>
<%= content_for(:facebook_card) do %><%= Carto::StaticMapsURLHelper.new.url_for_static_map(request, @visualization, 1200, 630) %><% end %>
<%= content_for(:css) do %>
<%= render :partial => 'admin/visualizations/public/embed_map_inline_css' %>
<% end %>
<%= content_for(:body_class) do %>
embed-map
<% end %>
<%= content_for(:content) do %>
<% if @visualization.public? || @visualization.public_with_link? || @visualization.password_protected? || @visualization.organization? %>
<div id="map"></div>
<div id="not_supported_dialog" style="display: none">
<h2>CARTO</h2>
<p>This visualization only works in modern browsers. Upgrade yours and enjoy.</p>
<ul>
<li><a href="http://www.apple.com/safari/" class="safari">Safari</a></li>
<li><a href="https://www.google.com/chrome/" class="chrome">Chrome</a></li>
<li class="last"><a href="http://www.mozilla.org/en-US/firefox/all/‎" class="firefox">Firefox</a></li>
</ul>
</div>
<div class="cartodb-text">
Map created by
<% username = @visualization.user.name_or_username %>
<a class="user" href="<%= CartoDB.url(self, 'public_user_feed_home', user: @visualization.user) %>?utm_source=Footer_Link&utm_medium=referral&utm_campaign=Embed_v1&utm_content=<%= @visualization.user.username %>" target="_blank">
<% if !@visualization.user.avatar_url.blank? %>
<img src="<%= @visualization.user.avatar_url %>" width="16" height="16" alt="<%= username %>" title="<%= username %>" />
<% end %>
<span class="username"><%= username %></span>
</a>
</div>
<% end %>
<% end %>
<%= content_for(:js) do %>
<%= insert_trackjs('embeds', Cartodb.get_config(:trackjs, 'frequency')) %>
<%= render :partial => 'admin/visualizations/public/embed_map_inline_js' %>
<% end %>
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Embed error | 快点</title>
<%= editor_stylesheet_link_tag 'password_protected.css' %>
<%= insert_google_tag_manager('embeds') %>
</head>
<body class='PublicPage-body PublicPage-background--grey'>
<%= insert_google_tag_manager_no_script('embeds') %>
<div class='PublicPage-centerContainer'>
<div class='PublicPage-container'>
<div class='PublicPage-protectedEmbed-iconContainer'>
<svg version="1.1" id="Outline_Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="50px" height="50px" viewBox="0 0 24 24">
<g id="Editor-private-embed" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path fill='#27353C' d="M17.479,11.035c-3.584,0-6.5,2.916-6.5,6.5s2.916,6.5,6.5,6.5s6.5-2.916,6.5-6.5S21.062,11.035,17.479,11.035z
M17.479,23.035c-3.033,0-5.5-2.467-5.5-5.5s2.467-5.5,5.5-5.5s5.5,2.467,5.5,5.5S20.511,23.035,17.479,23.035z"/>
<circle fill='#27353C' cx="17.479" cy="20.802" r="0.593"/>
<path fill='#27353C' d="M17.479,13.484c-1.256,0-2.277,1.022-2.277,2.278c0,0.276,0.224,0.5,0.5,0.5s0.5-0.224,0.5-0.5
c0-0.705,0.573-1.278,1.277-1.278c0.706,0,1.279,0.573,1.279,1.278c0,0.705-0.574,1.278-1.279,1.278c-0.276,0-0.5,0.224-0.5,0.5
v1.779c0,0.276,0.224,0.5,0.5,0.5s0.5-0.224,0.5-0.5v-1.334c1.017-0.229,1.779-1.138,1.779-2.223
C19.758,14.506,18.735,13.484,17.479,13.484z"/>
<path fill='#27353C' d="M1,1h10v4.5C11,5.776,11.224,6,11.5,6H16v4h1V5.5c0-0.067-0.014-0.132-0.039-0.192c-0.025-0.061-0.062-0.116-0.108-0.162
l-4.999-4.999c-0.046-0.046-0.101-0.083-0.162-0.108C11.632,0.014,11.567,0,11.5,0h-11C0.224,0,0,0.224,0,0.5v21
C0,21.776,0.224,22,0.5,22H11v-1H1V1z M12,1.707L15.293,5H12V1.707z"/>
</g>
</svg>
</div>
<p class='CDB-Text CDB-Size-large'>
未找到地图或数据表, 也许是没有登录权限. 请重新 <%= link_to "登录", login_url(after: request.original_url) %>
</p>
</div>
</div>
</body>
</html>
@@ -0,0 +1,40 @@
(function() {
function get_url_params(url, conversion) {
conversion = conversion || {};
if(!url) {
return {};
}
var search = url.split('?');
if(search.length < 2) {
return {};
}
search = search[1];
var tokens = search.split('&');
var params = {};
for(var i = 0; i < tokens.length; ++i) {
var tk = tokens[i].split('=');
var fn = conversion[tk[0]] || function(v) { return v };
if(tk.length === 2) {
params[tk[0]] = fn(decodeURIComponent(tk[1]));
}
}
return params;
}
var url = location.search;
var opt = get_url_params(url);
var height = opt.height || '400';
if(height.indexOf('%') == -1) {
height += 'px';
}
var l = document.createElement("a");
l.href = url
if(l.protocol.indexOf('http') != -1) {
var port = l.port ? ':' + l.port: '';
document.write('<iframe src="' + l.protocol + '//' + l.hostname + port + '/viz/embed_forbidden" frameborder="0" width="100%" height="' + height +'" ></iframe>');
}
})();
@@ -0,0 +1,27 @@
<%= content_for(:title) do %>
Protected embed
<% end %>
<%= content_for(:header_title) do %>
This embed is protected with password
<% end %>
<%= content_for(:password_form) do %>
<%= form_tag(CartoDB.url(self, 'protected_embed_map', params: { :protocol => Rails.env.development? ? 'http' : 'https' }) + '?' + request.query_string, {:method=>'POST',:authenticity_token=>false}) do %>
<div class='PublicPage-field-withTooltip'>
<%= password_field_tag 'password', params[:password], class: "PublicPage-form--inputText RoundBorders-all CDB-Text CDB-Size-medium is-light u-whiteTextColor #{ flash[:error].present? ? 'is-alert' : ''}", placeholder: 'Insert your password'%>
<%- if flash[:error].present? %>
<div class="PublicPage-inputTooltip CDB-InfoTooltip CDB-InfoTooltip--left u-lSpace--xl is-error">
<p class='CDB-Text CDB-Size-medium CDB-InfoTooltip-text'><%= flash[:error] %></p>
</div>
<% end %>
</div>
<% end %>
<% end %>
<%= content_for(:ua) do %>
embeds
<% end %>
@@ -0,0 +1,44 @@
<style type="text/css">
html, body, #map {height: 100%; padding: 0; margin: 0;}
/* footer */
.cartodb-text {position:absolute; display:none; bottom:0; left:0; right:0; margin:0; padding:0 10px; background:white; font:normal 11px "Helvetica",Arial; color:#999999; border-top:1px solid #CCC; border-top:1px solid rgba(0,0,0,0); box-shadow:rgba(0,0,0,0.6) 0 0 1px 0; -webkit-box-shadow:rgba(0,0,0,0.6) 0 0 1px 0; -moz-box-shadow:rgba(0,0,0,0.6) 0 0 1px 0; -o-box-shadow:rgba(0,0,0,0.6) 0 0 1px 0; line-height:29px; z-index:2; }
.cartodb-text a {color:#397DB8; text-decoration:underline;}
.cartodb-text a.user { text-decoration:none }
.cartodb-text img {display:inline-block; *display:inline; vertical-align:middle; border-radius:16px; -webkit-border-radius:16px; -moz-border-radius:16px; zoom:1; text-decoration:none }
.cartodb-text span.username { text-decoration:underline }
/* not supported dialog */
#not_supported_dialog {position:absolute; width:356px; height:213px; top:50%; left:50%; margin-top:-107px; margin-left:-178px; padding:0; background-color:#FFF; text-align:center; font-family:'Helvetica', Arial; color:#666666; z-index:10000;}
#not_supported_dialog h2 {display:inline-block; width:77px; margin:30px 0 0; padding-bottom:16px; font-size:13px; font-weight:bold; border-bottom:1px solid #D9D9D9; vertical-align:top; zoom:1; *display:inline;}
#not_supported_dialog p {display:block; padding:0 40px; margin:12px 0 0; font-size:15px;}
#not_supported_dialog ul {position:absolute; bottom:0; left:0; right:0; display:block; margin:0; padding:0; list-style:none; border-top:1px solid #D9D9D9;}
#not_supported_dialog ul li {float:left; margin:0; padding:0; border-right:1px solid #D9D9D9;}
#not_supported_dialog ul li a {display:block; width:118px; height:74px; background-repeat:no-repeat; background-position:center center; font-size:0; line-height:0; text-indent:-9999px;}
#not_supported_dialog ul li.last {border:none;}
#not_supported_dialog a.safari {background-image:url('<%= editor_image_path "layout/safari.png" %>');}
#not_supported_dialog a.chrome {background-image:url('<%= editor_image_path "layout/chrome.png" %>');}
#not_supported_dialog a.firefox {background-image:url('<%= editor_image_path "layout/firefox.png" %>');}
:-webkit-full-screen .cartodb-map-wrapper { height: 100%!important; }
:-moz-full-screen .cartodb-map-wrapper { height: 100%!important; }
:-ms-fullscreen .cartodb-map-wrapper { height: 100%!important; }
:fullscreen .cartodb-map-wrapper { height: 100%!important; }
<% if @hide_logo %>
<% else %>
/* Styles showing up new cartodb text */
<% if @visualization.user.remove_logo? && !Cartodb.config[:cartodb_com_hosted].present? %>
<% if !params['cartodb_logo'] || params['cartodb_logo'] == "true" %>
.cartodb-map-wrapper {bottom:30px!important;}
.cartodb-text {display:block;}
<% end %>
<% else %>
.cartodb-map-wrapper {bottom:30px!important;}
.cartodb-text {display:block;}
<% end %>
<% end %>
</style>
<%= editor_stylesheet_link_tag 'cartodb.css' %>
@@ -0,0 +1,155 @@
<% if @visualization.map.provider == 'googlemaps' %>
<%= insert_google_maps(@visualization.user.google_maps_query_string) %>
<% end %>
<%= editor_javascript_include_tag 'embed.js' %>
<script>
// Get url parameters
function get_url_params(conversion) {
conversion = conversion || {};
var tokens = location.search.slice(1).split('&');
var params = {};
for (var i = 0; i < tokens.length; ++i) {
var tk = tokens[i].split('=');
var fn = conversion[tk[0]] || function(v) { return v };
if (tk.length === 2) {
params[tk[0]] = fn(decodeURIComponent(tk[1]));
}
}
return params;
}
// Manage errors
function manageError(err, layer) {
if(layer && layer.get('type') === 'torque') {
$('#not_supported_dialog').show();
// hide all the overlays
var overlays = this.getOverlays()
for (var i = 0; i < overlays.length; ++i) {
var o = overlays[i];
o.hide && o.hide();
}
}
}
// Send stats
function stats() {
var browser;
var ua = navigator.userAgent;
var checks = [
['MSIE 11.0', 'ms11'],
['MSIE 10.0', 'ms10'],
['MSIE 9.0', 'ms9'],
['MSIE 8.0', 'ms8'],
['MSIE 7.0','ms7'],
['Chrome', 'chr'],
['Firefox', 'ff'],
['Safari', 'ff']
]
for(var i = 0; i < checks.length && !browser; ++i) {
if(ua.indexOf(checks[i][0]) !== -1) browser = checks[i][1];
}
browser = browser || 'none';
cartodb.core.Profiler.metric('cartodb-js.embed.' + browser).inc();
}
// On load...
$(function(){
// Set visualization user url prefix
cartodb.config.set('url_prefix', '<%= @visualization.user.public_url(nil, request.protocol == "https://" ? "https" : "http") %>');
var bool_fn = function(v) { return v == 'true' };
var is_custom_install = <%= Cartodb.config[:cartodb_com_hosted].present? %>;
var logo_fn = function(v) { return ( <%= !@visualization.user.remove_logo? %> || is_custom_install ) ? true : v == 'true' };
var layer_fn = function(v) {
if(!v || !v.length) {
return null;
}
return _.map(v.split("|"), function(v) {
return { visible: !!parseInt(v, 10) }
});
};
var opt = get_url_params({
'force_mobile': bool_fn,
'search': bool_fn,
'title': bool_fn,
'description': bool_fn,
'shareable': bool_fn,
'fullscreen': bool_fn,
'cartodb_logo': logo_fn,
'scrollwheel': bool_fn,
'sublayer_options': layer_fn,
'layer_selector': bool_fn,
'legends': bool_fn
});
<% if (@visualization.password_protected? or @visualization.is_privacy_private?) and @protected_map_tokens %>
opt.auth_token = [];
<% @protected_map_tokens.each do |token| %>
opt.auth_token.push('<%= token %>');
<% end %>
opt.https = true; // when auth_token is used tiles should be fetch using https
<% end %>
<% if Rails.env.development? || Cartodb.config[:no_cdn] == true %>
opt.no_cdn = true;
<% end %>
<% if @hide_logo %>
opt.cartodb_logo = false;
<% end %>
opt.mobile_layout = true;
cartodb.config.set({
cartodb_attributions: "CARTO <a href='https://carto.com/attributions?utm_source=Footer_Link&utm_medium=referral&utm_campaign=Embed_v1&utm_content=Attributions&utm_term=<%= @visualization.user.username %>' target='_blank'>attribution</a>",
cartodb_logo_link: "https://carto.com?utm_source=Footer_Link&utm_medium=referral&utm_campaign=Embed_v1&utm_content=Logo"
})
var loadingTime = cartodb.core.Profiler.metric('cartodb-js.embed.time_full_loaded').start();
var visReadyTime = cartodb.core.Profiler.metric('cartodb-js.embed.time_vis_loaded').start();
cartodb.createVis('map', <%= safe_js_object @visualization.to_vizjson({https_request: request.protocol == 'https://'}).to_json %>, opt, function(vis) {
visReadyTime.end();
vis.on('load', function() {
loadingTime.end();
});
window.vis = vis;
// fixes default position of the overlays
setTimeout(function() {
$(window).trigger("map_resized");
}, 400);
// some stats
stats();
}).on('error', manageError);
});
//<!-- load stats -->
<% if Cartodb.config[:graphite_public] %>
if (location.protocol.indexOf('https') === -1) {
jQuery.getScript('<%= javascript_path "statsc.js" %>', function(ready) {
statsc.connect('http://<%= Cartodb.config[:graphite_public]['host'] %>:<%= Cartodb.config[:graphite_public]['port'] %>/');
cartodb.core.Profiler.backend(function () {
statsc.send.apply(statsc, arguments);
})
// stop sending stats after 11 seconds
// statsc send stats in 5 secs interval so allow to send at least twice
setTimeout(function() {
cartodb.core.Profiler.backend(null);
}, 11*1000);
})
}
<% end %>
</script>
@@ -0,0 +1,16 @@
<%# Still used for public dataset page %>
<div class="cartodb-footer">
<div class="inner">
<div class="copyright embed-left-col">
<div class="content">
&copy; <%= Time.now.year %> CARTO - <a href="https://carto.com/signup" title="Create your own maps with CARTO">Create your own maps</a>
</div>
</div>
<div class="terms embed-right-col">
<div class="content">
<a href="https://carto.com/terms/" target="blank">Terms of Service</a> ·
<a href="https://carto.com/privacy/" target="blank">Privacy policy</a>
</div>
</div>
</div>
</div>
@@ -0,0 +1,248 @@
<% require_dependency 'static_maps_url_helper' %>
<%= content_for(:page_title) do %><%= @table.name.gsub(/_/," ") %><% end %>
<%= content_for(:description) do %><%= @table.description ? "#{@table.description}. Map created by #{@name} in CARTO" : "Map created by #{@name} in CARTO" %><% end %>
<%= content_for(:twitter_card) do %><%= Carto::StaticMapsURLHelper.new.url_for_static_map(request, @table.table_visualization, 560, 300) %><% end %>
<%= content_for(:facebook_card) do %><%= Carto::StaticMapsURLHelper.new.url_for_static_map(request, @table.table_visualization, 1200, 630) %><% end %>
<%= content_for(:css) do %>
<%= stylesheet_link_tag 'common_new', 'public_table_new', 'public_map_new' %>
<% end %>
<% content_for(:js) do %>
<% if @table.map.provider == 'googlemaps' %>
<%= insert_google_maps(@user.google_maps_query_string) %>
<% end %>
<%= javascript_include_tag 'common', 'common_vendor', 'public_table_new' %>
<script>
var table_name = '<%=raw @table.qualified_table_name %>';
var table_id = '<%= @table.id %>';
var schema = <%= safe_js_object @table.schema.to_json %>;
var user_name = '<%= @user.username %>';
var owner_username = '<%= @table.owner.username %>';
var belong_organization = <%= @table.owner.has_organization? %>;
var map = <%= safe_js_object @table.map.to_json %>;
var config = <%= safe_js_object frontend_config_public({https_apis: request.protocol == 'https://' }) %>;
var vizjson_obj = <%= safe_js_object @vizjson.to_json %>;
var auth_token = <%= safe_js_object @auth_tokens.to_json %>;
var use_https = <%= @use_https =%>;
var api_key = <%= safe_js_object @api_key.to_json %>;
var base_url = '<%= @table.owner.public_url(nil, request.protocol == "https://" ? "https" : "http") %>';
var login_url = "<%= CartoDB.url(self, 'login') %>";
</script>
<% end %>
<%= content_for(:content) do %>
<%= render 'admin/shared/public_header' %>
<div class="CDB-Text PublicMap-map js-map" id="map">
<div class="Spinner Spinner--center js-spinner"></div>
<div class="panes pane_table"></div>
<div class="panes pane_map"></div>
<div class="navigation u-showOnTablet">
<ul>
<li><a href="#/table" data-pane="table" class=" tab selected u-valign"><i class="Navmenu-tableIcon CDB-IconFont CDB-IconFont-table u-iblock u-malign"></i></a></li>
<li><a href="#/map" data-pane="map" class="u-valign"><i class="CDB-IconFont CDB-IconFont-map u-iblock u-malign"></i></a></li>
</ul>
</div>
</div>
<%# Legacy from current embed %>
<div class="NotSupportedDialog" id="not_supported_dialog" style="display: none">
<h2 class="NotSupportedDialog-title">CARTO</h2>
<p class="NotSupportedDialog-desc">This visualization only works in modern browsers. Upgrade yours and enjoy.</p>
<ul class="NotSupportedDialog-list">
<li class="NotSupportedDialog-item"><a class="NotSupportedDialog-itemLink NotSupportedDialog-itemLink--Safari" href="http://www.apple.com/safari/" class="safari">Safari</a></li>
<li class="NotSupportedDialog-item"><a class="NotSupportedDialog-itemLink NotSupportedDialog-itemLink--Chrome" href="https://www.google.com/chrome/" class="chrome">Chrome</a></li>
<li class="NotSupportedDialog-item is-last"><a class="NotSupportedDialog-itemLink NotSupportedDialog-itemLink--Firefox" href="http://www.mozilla.org/en-US/firefox/all/‎" class="firefox">Firefox</a></li>
</ul>
</div>
<div class="separator bottom"></div>
<div class="CDB-Text CDB-Size-medium Navmenu js-Navmenu">
<div class="u-inner">
<div class="PublicMap-block">
<div class="PublicMap-gradient"></div>
<div class="PublicMap-leftBlock PublicMap-leftBlock--owner">
<ul class="Navmenu-list Navmenu-list--owner Navmenu-list--avatar">
<li class="Navmenu-item">
<a href="<%= @user_url %>" class="UserAvatar">
<img class="UserAvatar-img--medium" src="<%= @visualization.user.avatar %>" alt="<%= @name %>" title="<%= @name %>" />
</a>
</li>
</ul>
<ul class="Navmenu-list Navmenu-list--owner">
<li class="Navmenu-item u-hideOnTablet last-child">
<a href="<%= @user_url %>" class="Navmenu-link Navmenu-link--owner" title="<%= @name %>"><%= @name %></a>
</li>
<% unless @is_data_library %>
<li class="Navmenu-item">
<i class="Navmenu-rarrow CDB-IconFont CDB-IconFont-rArrowLight"></i>
<a href="<%= CartoDB.url(self, 'public_datasets_home', user: @visualization.user) %>" class="Navmenu-link">Datasets</a>
</li>
<% end %>
</ul>
</div>
<div class="PublicMap-rightBlock PublicMap-rightBlock--owner u-txt-right">
<ul class="Navmenu-list">
<li class="Navmenu-item Navmenu-item--action Navmenu-item--withsep u-hideOnTablet">
<div class="Navmenu-sep"></div>
<i class="Navmenu-actionIcon CDB-IconFont CDB-IconFont-markup"></i>
<a href="#" class="Navmenu-link Navmenu-link--action js-Navmenu-link--api">API call</a>
</li>
<li class="Navmenu-item Navmenu-item--action u-hideOnTablet">
<i class="Navmenu-actionIcon CDB-IconFont CDB-IconFont-floppy"></i>
<a href="#" class="Navmenu-link Navmenu-link--action js-Navmenu-link--download">Download</a>
</li>
<% if !Cartodb.config[:cartodb_com_hosted].present? %>
<li class="Navmenu-item u-hideOnTablet">
<a class="Button Button--main Navmenu-editLink Navmenu-editLink--edit Navmenu-editLink--oneclick is-active js-oneclick" href="https://oneclick.carto.com/?file=<%= CGI.escape( @export_sql_api_url ) %>&provider=<%= URI.encode(@table.owner.username) %>&logo=<%= URI.encode(@avatar_url) %>">Create map</a>
<a href="<%= CartoDB.url(self, 'public_tables_show', params: { id: @table.name }, user: @table.owner.organization ? @table.owner : nil) %>" class="Button Button--main Navmenu-editLink Navmenu-editLink--edit Navmenu-editLink--oneclick js-edit">Edit in CARTO</a>
</li>
<% end %>
</ul>
</div>
</div>
</div>
</div>
<div class="CDB-Text PublicMap-secondary PublicMap-secondary--bottom">
<div class="u-inner">
<div class="PublicMap-block">
<div class="PublicMap-leftBlock PublicMap-leftBlock--large">
<div class="js-user-meta">
<h1 class="PublicMap-title js-PublicMap-title Title Title--m"><%= @visualization.display_name_or_name %></h1>
<% if @visualization.description.present? %>
<div class="PublicMap-description"><%= raw markdown_html_safe(@visualization.description) %></div>
<% end %>
<div class="PublicMap-meta">
<ul class="PublicMap-metaList">
<li class="PublicMap-metaItem"><i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-calendar"></i> <span title="<%= time_ago_in_words(@visualization.updated_at) %> ago"><%= time_ago_in_words(@visualization.updated_at) %> ago</span></li>
</ul>
<ul class="PublicMap-metaList PublicMap-metaList--mobile js-PublicMap-metaList--mobile">
<% if !@table.rows_counted.blank? %>
<li class="PublicMap-metaItem">
<i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-rows RowsIndicator-icon"></i>
<% if @table.rows_counted < 10000 %>
<%= number_with_delimiter(@table.rows_counted) %>
<% else %>
<%= number_to_human(@table.rows_counted, units: { unit:"", thousand: "K", million: "M" }, precision: 2, format: '%n%u') %>
<% end %>
<span title="<%= 'row'.pluralize(@table.rows_counted) %>"><%= 'row'.pluralize(@table.rows_counted) %></span>
</li>
<% end %>
<% if !@visualization.visualization.license_info.nil? %>
<li class="PublicMap-metaItem">
<%# Defaulting on CC icon for license https://github.com/CartoDB/cartodb/issues/6413 %>
<i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-creativeCommons iconFont-License iconFont-License<%= @visualization.visualization.license_info.id.to_s.gsub(/_/,"").downcase %>"></i>
<%# Keep on one line to avoid unwanted spaces %>
<span title="<%= @visualization.visualization.license_info.name %>"><%= @visualization.visualization.license_info.name %></span>
</li>
<% end %>
<% if @visualization.visualization.source.present? %>
<li class="PublicMap-metaItem">
<i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-anchor"></i>
<%# Keep on one line to avoid unwanted spaces %>
<span title="<%= @visualization.visualization.source %>"><%= raw markdown_html_safe(@visualization.source) %></span>
</li>
<% end %>
</ul>
</div>
<a class="Navmenu-editLink Navmenu-editLink--more js-Navmenu-editLink--more" href="#/more">More info</a>
</div>
</div>
</div>
</div>
<%# Related maps %>
<% if @total_visualizations.count > 0 %>
<div class="u-inner">
<div class="PublicMap-block with-padding">
<h3 class="PublicMap-secondaryTitle">Maps using this dataset</h3>
</div>
</div>
<ul class="MapsList PublicMap-mapsList">
<% @total_visualizations.last(3).each do |vis| %>
<li class="MapsList-item">
<div class="MapCard" data-vis-id="<%= vis.id %>" data-vis-owner-name="<%= vis.user[:username] %>">
<a href="<%= CartoDB.url(self, 'public_visualizations_public_map', params: { id: vis.id }, user: vis.user) %>" class="MapCard-header js-header">
<div class="MapCard-loader"></div>
</a>
<div class="MapCard-content MapCard-content--compact">
<div class="MapCard-contentBody">
<div class="MapCard-contentBodyRow MapCard-contentBodyRow--flex">
<h3 class="MapCard-title DefaultTitle CDB-Text is-semibold CDB-Size-large">
<a href="<%= CartoDB.url(self, 'public_visualizations_public_map', params: { id: vis.id }, user: vis.user) %>" class="DefaultTitle-link u-ellipsLongText" title="<%= vis.name %>"><%= vis.name %></a>
</h3>
</div>
<div class="MapCard-contentFooterTimeDiff DefaultTimeDiff CDB-Text CDB-Size-medium u-altTextColor">
<i class="CDB-IconFont CDB-IconFont-clock DefaultTimeDiff-icon"></i>
<%= time_ago_in_words(vis.updated_at) %> ago
</div>
</div>
</div>
</div>
</li>
<% end %>
<%# at most 3 cards per line, visbility is handled by CSS depending on viewport size %>
<% if @total_visualizations.count < 3 %>
<% ((3 - @total_visualizations.count + 3) % 3).times.each do %>
<li class="MapsList-item MapsList-item--fake">
<div class="MapCard">
<div class="MapCard-header MapCard-header--fake"></div>
<div class="MapCard-content MapCard-content--compact"></div>
</div>
</li>
<% end %>
<% end %>
</ul>
<% end %>
<%# DISQUS %>
<% if @table.owner.disqus_shortname.present? %>
<div class="u-inner">
<div class="PublicMap-block PublicMap-info">
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = '<%= @disqus_shortname %>';
var disqus_identifier = '<%= @visualization.id %>';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
</div>
</div>
</div>
<% end %>
<% if cartodb_com_hosted? %>
<%= render 'admin/shared/footer', :light => true %>
<% else %>
<%= render 'admin/shared/public_footer', :light => false %>
<% end %>
<% end %>
@@ -0,0 +1,415 @@
<% require_dependency 'static_maps_url_helper' %>
<%= content_for(:title) do %><%= @visualization.name %><% end %>
<%= content_for(:description) do %><%= @visualization.description.present? ? "#{markdown_html_clean(@visualization.description)} — Map created by #{@name} in CARTO" : "Map created by #{@name} in CARTO" %><% end %>
<%= content_for(:twitter_card) do %><%= Carto::StaticMapsURLHelper.new.url_for_static_map(request, @visualization, 560, 300) %><% end %>
<%= content_for(:facebook_card) do %><%= Carto::StaticMapsURLHelper.new.url_for_static_map(request, @visualization, 1200, 630) %><% end %>
<%= content_for(:body_class) do %> PublicMap <% end %>
<%= content_for(:css) do %>
<%= editor_stylesheet_link_tag 'cartodb', 'common', 'public_map' %>
<% end %>
<%= content_for(:content) do %>
<% if @visualization.is_accesible_by_user?(current_user) %>
<%= render 'admin/shared/public_header' %>
<div class="PublicMap-map js-map" id="map">
<div class="Spinner Spinner--center js-spinner"></div>
</div>
<%# Legacy from current embed %>
<div class="NotSupportedDialog" id="not_supported_dialog" style="display: none">
<h2 class="NotSupportedDialog-title">CARTO</h2>
<p class="NotSupportedDialog-desc">This visualization only works in modern browsers. Upgrade yours and enjoy.</p>
<ul class="NotSupportedDialog-list">
<li class="NotSupportedDialog-item"><a class="NotSupportedDialog-itemLink NotSupportedDialog-itemLink--Safari" href="http://www.apple.com/safari/" class="safari">Safari</a></li>
<li class="NotSupportedDialog-item"><a class="NotSupportedDialog-itemLink NotSupportedDialog-itemLink--Chrome" href="https://www.google.com/chrome/" class="chrome">Chrome</a></li>
<li class="NotSupportedDialog-item is-last"><a class="NotSupportedDialog-itemLink NotSupportedDialog-itemLink--Firefox" href="http://www.mozilla.org/en-US/firefox/all/‎" class="firefox">Firefox</a></li>
</ul>
</div>
<div class="CDB-Text CDB-Size-medium Navmenu js-Navmenu">
<div class="u-inner">
<div class="PublicMap-block">
<div class="PublicMap-gradient"></div>
<div class="PublicMap-leftBlock PublicMap-leftBlock--owner">
<ul class="Navmenu-list Navmenu-list--owner Navmenu-list--avatar">
<li class="Navmenu-item">
<a href="<%= CartoDB.url(self, 'public_user_feed_home', user: @visualization.user) %>" target="_blank" class="UserAvatar">
<img class="UserAvatar-img--medium" src="<%= @visualization.user.avatar %>" alt="<%= @name %>" title="<%= @name %>" />
</a>
</li>
</ul>
<ul class="Navmenu-list Navmenu-list--owner">
<li class="Navmenu-item u-hideOnTablet last-child">
<a href="<%= CartoDB.url(self, 'public_user_feed_home', user: @visualization.user) %>" class="Navmenu-link Navmenu-link--owner" title="<%= @name %>"><%= @name %></a>
</li>
<li class="Navmenu-item">
<i class="Navmenu-rarrow CDB-IconFont CDB-IconFont-rArrowLight"></i>
<a href="<%= CartoDB.url(self, 'public_maps_home', user: @visualization.user) %>" class="Navmenu-link">Maps</a>
</li>
</ul>
</div>
<div class="PublicMap-rightBlock PublicMap-rightBlock--owner u-txt-right">
<ul class="Navmenu-list">
<li class="Navmenu-item Navmenu-item--buttons">
<ul class="u-valign">
<li class="Navmenu-subItem">
<a href="<%= CartoDB.url(self, 'public_visualizations_embed_map', params: { id: @visualization.id }, user: @visualization.user) %>" target="_blank" class="Navmenu-link">
<i class="CDB-IconFont CDB-IconFont-fullscreen Navmenu-icon"></i>
</a>
</li>
<li class="Navmenu-subItem">
<a href="#" class="Navmenu-link js-Navmenu-link--download-map">
<i class="CDB-IconFont CDB-IconFont-downloadCircle Navmenu-icon"></i>
</a>
</li>
</ul>
</li>
<li class="Navmenu-item Navmenu-item--buttons js-Navmenu-share u-showOnTablet">
<div class="Navmenu-sep u-showOnTablet"></div>
<a href="#" class="Navmenu-link Navmenu-shareLink js-Navmenu-shareLink">
<i class="CDB-IconFont CDB-IconFont-share Navmenu-icon"></i>
</a>
</li>
</ul>
<ul class="Navmenu-list Navmenu-shareList js-Navmenu-shareList u-valign">
<li class="Navmenu-item Navmenu-item--buttons">
<div class="Navmenu-sep u-hideOnTablet"></div>
<ul class="u-valign">
<li class="Navmenu-subItem">
<a href="https://twitter.com/intent/tweet?text=<%= url_encode(@visualization.name) %>&url=<%= url_encode(request.original_url) %>&via=CARTO">
<i class="CDB-IconFont CDB-IconFont-twitter Navmenu-icon Navmenu-icon--twitter"></i>
</a>
</li>
<li class="Navmenu-subItem">
<a href="http://www.facebook.com/sharer.php?u=<%= url_encode(request.original_url) %>" target="_blank" class="Navmenu-link js-Navmenu-link--facebook">
<i class="CDB-IconFont CDB-IconFont-facebookSquare Navmenu-icon"></i>
</a>
</li>
<li class="Navmenu-subItem">
<a href="https://www.linkedin.com/shareArticle?mini=true&url=<%= url_encode(request.original_url) %>&title=<%= url_encode(@visualization.name) %>&summary=<%= url_encode(@visualization.description.present? ? "#{markdown_html_clean(@visualization.description)} — Map created by #{@name} in CARTO" : "Map created by #{@name} in CARTO") %>&source=CARTO" target="_blank" class="Navmenu-link js-Navmenu-link--linkedin">
<i class="CDB-IconFont CDB-IconFont-linkedin Navmenu-icon"></i>
</a>
</li>
<li class="Navmenu-subItem u-showOnTablet">
<button class="ImportItem-closeButton Navmenu-link js-Navmenu-closeLink Navmenu-closeLink">
<i class="CDB-IconFont CDB-IconFont-close ImportItem-closeButtonIcon"></i>
</button>
</li>
</ul>
</li>
</ul>
<ul class="Navmenu-list u-hideOnTablet">
<li class="Navmenu-item">
<a class="Button Button--main Navmenu-editLink Navmenu-editLink--edit js-Navmenu-editLink" href="<%= CartoDB.url(self, 'public_visualizations_show', params: { id: @visualization.id }, user: @visualization.user) %>">Edit in CARTO</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="CDB-Text PublicMap-secondary">
<div class="u-inner">
<div class="PublicMap-block">
<div class="PublicMap-leftBlock PublicMap-leftBlock--large">
<div class="js-user-meta">
<h1 class="PublicMap-title js-PublicMap-title Title Title--m"><%= @visualization.name %></h1>
<% if @visualization.description.present? %>
<div class="PublicMap-description"><%= raw markdown_html_safe(@visualization.description) %></div>
<% end %>
<div class="PublicMap-meta">
<ul class="PublicMap-metaList">
<li class="PublicMap-metaItem"><i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-calendar"></i> <%= time_ago_in_words(@visualization.updated_at) %> ago</li>
</ul>
<ul class="PublicMap-metaList PublicMap-metaList--mobile js-PublicMap-metaList--mobile">
<li class="PublicMap-metaItem"><i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-stats"></i> <%= number_with_delimiter(@mapviews) %> <%= 'mapview'.pluralize(@mapviews) %></li>
<% if @visualization.tags.size > 0 %>
<li class="PublicMap-metaItem">
<i class="PublicMap-metaIcon CDB-IconFont CDB-IconFont-label"></i>
<%# Keep on one line to avoid unwanted spaces %>
<% formatted_tags(@visualization.tags) do |tag| %><a class="PublicMap-metaLink" href="<%= CartoDB.url(self, 'public_tag', params: { tag: tag }, user: @visualization.user) %>"><%= tag %></a><% end %>
</li>
<% end %>
</ul>
</div>
<a class="Navmenu-editLink Navmenu-editLink--more js-Navmenu-editLink--more" href="#/more">More info</a>
</div>
</div>
</div>
</div>
<%# Datasets %>
<div class="u-inner">
<div class="PublicMap-block with-padding">
<h3 class="PublicMap-secondaryTitle">Datasets in use</h3>
</div>
</div>
<div class="u-inner">
<div class="PublicMap-block">
<ul>
<% if @related_canonical_visualizations.present? %>
<% @related_canonical_visualizations.each do |vis| %>
<% if vis.privacy == "public" %>
<li class="DatasetsList-item">
<div class="DatasetsList-itemCategory is--<%= vis.related_visualizations_simple_geometry_types[0] if vis.related_visualizations_simple_geometry_types.present? %>Dataset"></div>
<div class="DatasetsList-itemInfo">
<div class="DatasetsList-itemPrimaryInfo">
<h3 class="DatasetsList-itemTitle DefaultTitle u-ellipsLongText CDB-Text CDB-Size-large u-mainTextColor">
<a href="<%= CartoDB.url(self, 'public_table', params: { id: vis.user_table.name }, user: @user_domain.nil? ? nil : @related_tables_owners[vis.user_table.user_id]) %>" title="<%= vis.user_table.name %>" class="DefaultTitle-link u-ellipsLongText"><%= vis.user_table.name %></a>
</h3>
<% if vis.description %>
<div class="DefaultDescription DatasetsList-itemDescription u-ellipsLongText CDB-Text CDB-Size-medium u-altTextColor"><%= raw markdown_html_safe(vis.description) %></div>
<% end %>
</div>
</div>
<div class="DatasetsList-itemSecondaryInfo">
<div class="DatasetsList-itemMeta CDB-Size-medium">
<span class="CDB-Tag CDB-Text CDB-Size-small is-semibold u-upperCase PrivacyIndicator is-<%= vis.privacy %> u-hideOnTablet"><%= vis.privacy %></span>
<% if (vis.user_table.service.rows_counted) %>
<span class="RowsIndicator u-hideOnTablet">
<i class="CDB-IconFont CDB-IconFont-rows RowsIndicator-icon u-altTextColor CDB-Size-small"></i>
<%= "#{number_to_human(vis.user_table.service.rows_counted, format: "%n%u", units: { unit: "", thousand: "K", million: "M" }, delimiter: ",")} row#{vis.user_table.service.rows_counted.size == 1 ? "" : "s"}" %>
</span>
<% end %>
<span class="DatasetsList-itemTimeDiff DefaultTimeDiff u-hideOnTablet">
<i class="CDB-IconFont CDB-IconFont-clock DefaultTimeDiff-icon"></i>
<%= time_ago_in_words(vis.updated_at) %> ago
<% if vis.user.username != @visualization.user.username %>
by
<span class="UserAvatar">
<img class="UserAvatar-img UserAvatar-img--smaller" src="<%= vis.user.avatar_url %>" alt="<%= vis.user.name_or_username %>" title="<%= vis.user.name_or_username %>" />
</span>
<% end %>
</span>
</div>
</div>
</li>
<% end %>
<% end %>
<% end %>
<% if @nonpublic_tables_count.present? && @nonpublic_tables_count > 0 %>
<li class="DatasetsList-item">
<div class="LayoutIcon">
<i class="CDB-IconFont CDB-IconFont-lock"></i>
</div>
<div class="DefaultTitle PublicMap-privateDatasets"><%= pluralize(@nonpublic_tables_count, 'private dataset') %></div>
</li>
<% end %>
</ul>
</div>
</div>
<%# DISQUS %>
<% if @visualization.user.disqus_shortname.present? %>
<div class="u-inner">
<div class="PublicMap-block PublicMap-info">
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = '<%= @disqus_shortname %>';
var disqus_identifier = '<%= @visualization.id %>';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
</div>
</div>
<% end %>
<%# Related %>
<% if @more_visualizations && @more_visualizations.count > 0 %>
<div class="u-inner">
<div class="PublicMap-block">
<h3 class="PublicMap-secondaryTitle">More from <%= @name %></h3>
</div>
</div>
<ul class="MapsList PublicMap-mapsList">
<% @more_visualizations.each do |vis| %>
<li class="MapsList-item">
<div class="MapCard" data-vis-id="<%= vis.id %>" data-vis-owner-name="<%= vis.user.username %>">
<a href="<%= CartoDB.url(self, 'public_visualizations_public_map', params: { id: vis.id }, user: vis.user) %>" class="MapCard-header js-header">
<div class="MapCard-loader"></div>
</a>
<div class="MapCard-content MapCard-content--compact">
<div class="MapCard-contentBody">
<div class="MapCard-contentBodyRow MapCard-contentBodyRow--flex">
<h3 class="MapCard-title DefaultTitle CDB-Text is-semibold CDB-Size-large">
<a href="<%= CartoDB.url(self, 'public_visualizations_public_map', params: { id: vis.id }, user: vis.user) %>" class="DefaultTitle-link u-ellipsLongText" title="<%= vis.name %>"><%= vis.name %></a>
</h3>
</div>
<div class="MapCard-contentFooterTimeDiff DefaultTimeDiff CDB-Text CDB-Size-medium u-altTextColor">
<i class="CDB-IconFont CDB-IconFont-clock DefaultTimeDiff-icon"></i>
<%= time_ago_in_words(vis.updated_at) %> ago
</div>
</div>
</div>
</div>
</li>
<% end %>
<%# at most 3 cards per line, visbility is handled by CSS depending on viewport size %>
<% ((3 - @more_visualizations.count + 3) % 3).times.each do %>
<li class="MapsList-item MapsList-item--fake">
<div class="MapCard">
<div class="MapCard-header MapCard-header--fake"></div>
<div class="MapCard-content MapCard-content--compact"></div>
</div>
</li>
<% end %>
</ul>
<% end %>
</div>
<% if cartodb_com_hosted? %>
<%= render 'admin/shared/footer', :light => true %>
<% else %>
<%= render 'admin/shared/public_footer', :light => false %>
<% end %>
<% end %>
<% end %>
<%= content_for(:js) do %>
<%= insert_trackjs('embeds', Cartodb.get_config(:trackjs, 'frequency')) %>
<% if @visualization.map.provider == 'googlemaps' %>
<%= insert_google_maps(@google_maps_query_string) %>
<% end %>
<script>
function get_url_params(conversion) {
conversion = conversion || {};
var tokens = location.search.slice(1).split('&');
var params = {};
for (var i = 0; i < tokens.length; ++i) {
var tk = tokens[i].split('=');
var fn = conversion[tk[0]] || function(v) { return v };
if (tk.length === 2) {
params[tk[0]] = fn(decodeURIComponent(tk[1]));
}
}
return params;
}
var user_name = '<%= @user_domain %>';
var owner_username = '<%= @visualization.user.username %>';
var base_url = '<%= @visualization.user.public_url(nil, request.protocol == 'https://' ? 'https' : 'http') %>';
var vis_id = "<%= @visualization.id %>";
var vis_name = "<%= @visualization.name %>";
var belong_organization = <%= @visualization.user.has_organization? %>;
var config = <%= safe_js_object frontend_config_public({https_apis: request.protocol == 'https://' }) %>;
var vizdata = <%= safe_js_object @visualization.to_vizjson({https_request: request.protocol == 'https://'}).to_json %>;
var login_url = "<%= CartoDB.url(self, 'login') %>";
// Generating map options
var bool_fn = function(v) { return v == 'true' };
var is_custom_install = <%= Cartodb.config[:cartodb_com_hosted].present? %>;
var logo_fn = function(v) { return ( <%= !@visualization.user.remove_logo? %> || is_custom_install ) ? true : v == 'true' };
var layer_fn = function(v) {
if (!v || !v.length) {
return null;
}
return _.map(v.split("|"), function(v) {
return { visible: !!parseInt(v, 10) }
});
};
var map_options = get_url_params({
'search': bool_fn,
'title': bool_fn,
'description': bool_fn,
'shareable': bool_fn,
'fullscreen': bool_fn,
'cartodb_logo': bool_fn,
'scrollwheel': bool_fn,
'sublayer_options': layer_fn,
'layer_selector': bool_fn,
'legends': bool_fn
});
<% if (@visualization.password_protected? or @visualization.is_privacy_private?) and @protected_map_tokens %>
map_options.auth_token = [];
<% @protected_map_tokens.each do |token| %>
map_options.auth_token.push('<%= token %>');
<% end %>
map_options.https = true; // when auth_token is used tiles should be fetch using https
<% end %>
<% if Rails.env.development? || Cartodb.config[:no_cdn] == true %>
map_options.no_cdn = true;
<% end %>
// Description and title should be hidden
// because we already have that info
map_options.description = false;
map_options.title = false;
// Logo MUST be hidden in this view
map_options.cartodb_logo = false;
// Fullscreen button should be hidden
// because we already have a full page button
map_options.fullscreen = false;
map_options.scrollwheel = false;
map_options.mobile_layout = true;
</script>
<%= editor_javascript_include_tag 'cdb.js', 'templates.js', 'public_map_deps', 'public_map' %>
<script>
$(function() {
<% if Cartodb.config[:graphite_public] %>
if (location.protocol.indexOf('https') === -1) {
jQuery.getScript('<%= javascript_path "statsc.js" %>', function(ready) {
statsc.connect('http://<%= Cartodb.config[:graphite_public]['host'] %>:<%= Cartodb.config[:graphite_public]['port'] %>/');
cartodb.core.Profiler.backend(function () {
statsc.send.apply(statsc, arguments);
})
// stop sending stats after 11 seconds
// statsc send stats in 5 secs interval so allow to send at least twice
setTimeout(function() {
cartodb.core.Profiler.backend(null);
}, 11*1000);
})
}
<% end %>
});
</script>
<% end %>
@@ -0,0 +1,27 @@
<%= content_for(:title) do %>
Protected map
<% end %>
<%= content_for(:header_title) do %>
This map is protected with password
<% end %>
<%= content_for(:password_form) do %>
<%= form_tag(CartoDB.url(self, 'protected_public_map', params: { :protocol => Rails.env.development? ? 'http' : 'https'}) + '?' + request.query_string, { :method => 'POST', :authenticity_token => false}) do %>
<div class='PublicPage-field-withTooltip'>
<%= password_field_tag 'password', params[:password], class: "PublicPage-form--inputText RoundBorders-all CDB-Text CDB-Size-medium is-light u-whiteTextColor #{ flash[:error].present? ? 'is-alert' : ''}", placeholder: 'Insert your password'%>
<%- if flash[:error].present? %>
<div class="PublicPage-inputTooltip CDB-InfoTooltip CDB-InfoTooltip--left u-lSpace--xl is-error">
<p class='CDB-Text CDB-Size-medium CDB-InfoTooltip-text'><%= flash[:error] %></p>
</div>
<% end %>
</div>
<% end %>
<% end %>
<%= content_for(:ua) do %>
primary
<% end %>
@@ -0,0 +1,26 @@
<% content_for(:page_title) do %>
<%= @visualization.name %> |
<% end %>
<% content_for(:css) do %>
<%= editor_stylesheet_link_tag 'old_common_without_core.css', 'common.css', 'cdb.css', 'table.css', 'editor.css', 'map.css', :media => 'all' %>
<% end %>
<script type="text/javascript" id="dropboxjs" src="//www.dropbox.com/static/api/1/dropins.js" data-app-key="<%= Cartodb.config[:dropbox_api_key] %>"></script>
<script>
var vis_data = <%= safe_js_object @visualization.to_hash.to_json %>;
var user_data = <%= safe_js_object current_user.data({ show_api_calls: false }).to_json %>;
var config = <%= safe_js_object frontend_config %>;
var map_data = <%= safe_js_object @visualization.map.public_values.to_json %>;
var basemaps = <%=raw Cartodb.config[:basemaps].present? ? Cartodb.config[:basemaps].to_json.html_safe: 'null' %>;
var authTokens = <%= safe_js_object @auth_tokens.to_json %>;
</script>
<% content_for(:js) do %>
<% if !@google_maps_query_string.blank? %>
<%= insert_google_maps(@google_maps_query_string) %>
<% end %>
<%= editor_javascript_include_tag 'cdb.js','models.js', 'templates.js', 'templates_mustache.js', 'table.js', 'editor.js' %>
<% end %>
<div class="panes"></div>
@@ -0,0 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<body>
</body>
</html>