Initial commit
This commit is contained in:
Executable
+22
@@ -0,0 +1,22 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-column-included') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<% if (aggregate_function === 'count') { %>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">count_vals</div>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">count_vals_density</div>
|
||||
</li>
|
||||
<% } else {%>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue"><%- aggregate_function %>_<%- aggregate_column %></div>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.aggregate-intersection.description') %>
|
||||
</p>
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.geometries-updated') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">the_geom</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.area-of-influence.the-geom') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.area-of-influence.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/areas-of-influence" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-created') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">the_geom</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.centroid.the-geom') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">value</div>
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<% if (aggregation) { %>
|
||||
<%- _t('analyses-onboarding.centroid.aggregated-value') %>
|
||||
<% } else { %>
|
||||
<%- _t('analyses-onboarding.centroid.non-aggregated-value') %>
|
||||
<% } %>
|
||||
</p>
|
||||
</li>
|
||||
<% if (category_column) { %>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">category</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.centroid.category') %></p>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.centroid.description') %>
|
||||
</p>
|
||||
@@ -0,0 +1,18 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-created') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">the_geom</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.closest.the-geom') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">source_cdb_id</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.closest.source_cdb_id') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.closest.description') %>
|
||||
</p>
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.geometries-updated') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">the_geom</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.connect-with-lines.the-geom') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.connect-with-lines.' + type) %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/connect-with-lines" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
lib/assets/javascripts/builder/components/onboardings/analysis/analyses/data-observatory-measure.tpl
Executable
+18
@@ -0,0 +1,18 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-column-included') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue"><%- final_column %></div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.data-observatory-measure.custom-column') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.data-observatory-measure.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/enrich-from-data-observatory" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-included') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<% _.each(column_names, function (column) { %>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue"><%- column %></div>
|
||||
</li>
|
||||
<% }); %>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.data-observatory-multiple-measures.custom-columns') %>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.data-observatory-multiple-measures.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/enrich-from-data-observatory" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.filter-by-node-column.description') %>
|
||||
</p>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-created') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.filter.description') %>
|
||||
</p>
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.geometries-updated') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">the_geom</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.georeference.the-geom') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.georeference.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/georeference" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.geometries-updated') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">the_geom</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.group-points.the-geom') %></p>
|
||||
</li>
|
||||
<% if (category_column) { %>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue"><%- category_column %></div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.group-points.category') %></p>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.group-points.description', { method: _t('analyses.' + type + '.title') }) %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="http://postgis.net/docs/manual-2.2/" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.read-more') %></a>
|
||||
</p>
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-column-included') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">source_cartodb_id</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.intersection.source-cartodb-id') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.intersection.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/intersect-second-layer" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-column-added') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">cluster_no</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.kmeans.cluster-no', { clusters: clusters }) %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.kmeans.description') %>
|
||||
</p>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-included-based-on-input') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.merge.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/join-column-from-second-layer" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-included') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">quads</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.moran.quads') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">significance</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.moran.significance') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">moran</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.moran.moran') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">vals</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.moran.vals') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.moran.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/detect-outliers-and-clusters" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.no-new-columns') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.sampling.description', { percentage: Math.round(sampling * 100) }) %>
|
||||
</p>
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
<p class="CDB-Text Onboarding-headerDescription">
|
||||
<%- _t('analyses-onboarding.new-columns-included') %>
|
||||
</p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">trend</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.spatial-markov-trend.trend') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">trend_up</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.spatial-markov-trend.trend_up') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">trend_down</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.spatial-markov-trend.trend_down') %></p>
|
||||
</li>
|
||||
<li class="Onboarding-listItem">
|
||||
<div class="Onboarding-listItemValue">volatility</div>
|
||||
<p class="CDB-Text Onboarding-description"><%- _t('analyses-onboarding.spatial-markov-trend.volatility') %></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<%- _t('analyses-onboarding.spatial-markov-trend.description') %>
|
||||
</p>
|
||||
|
||||
<p class="CDB-Text Onboarding-description">
|
||||
<a href="https://carto.com/learn/guides/analysis/predict-trends-and-volatility" class="Onboarding-readMore" target="_blank"><%- _t('analyses-onboarding.learn-more') %></a>
|
||||
</p>
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
var LocalStorage = require('builder/components/local-storage/local-storage');
|
||||
var AnalysisOnboardingView = require('builder/components/onboardings/analysis/analysis-view');
|
||||
var Analyses = require('builder/data/analyses');
|
||||
|
||||
var BASE_STORAGE_KEY = 'onboarding';
|
||||
|
||||
var launcher = (function () {
|
||||
var onboardings;
|
||||
var userModel;
|
||||
var editorModel;
|
||||
var visDefinitionModel;
|
||||
|
||||
function init (opts) {
|
||||
if (!onboardings && !opts) {
|
||||
throw new Error('onboardings is required');
|
||||
}
|
||||
|
||||
if (!userModel && !opts) {
|
||||
throw new Error('userModel is required');
|
||||
}
|
||||
|
||||
if (!visDefinitionModel && !opts) {
|
||||
throw new Error('visDefinitionModel is required');
|
||||
}
|
||||
|
||||
if (!onboardings && opts && opts.onboardings) {
|
||||
onboardings = opts.onboardings;
|
||||
}
|
||||
|
||||
if (!userModel && opts && opts.userModel) {
|
||||
userModel = opts.userModel;
|
||||
}
|
||||
|
||||
if (!visDefinitionModel && opts && opts.visDefinitionModel) {
|
||||
visDefinitionModel = opts.visDefinitionModel;
|
||||
}
|
||||
|
||||
editorModel = onboardings.editorModel;
|
||||
}
|
||||
|
||||
return {
|
||||
init: function (opts) {
|
||||
init(opts);
|
||||
|
||||
var storageKey = BASE_STORAGE_KEY + '.' + visDefinitionModel.get('id');
|
||||
|
||||
LocalStorage.init(storageKey, {
|
||||
userModel: userModel
|
||||
});
|
||||
},
|
||||
|
||||
launch: function (type, model) {
|
||||
var genericType = Analyses.getAnalysisByType(type).genericType || type;
|
||||
|
||||
if (!LocalStorage.get(genericType) && genericType) {
|
||||
onboardings.create(function (modalModel) {
|
||||
return new AnalysisOnboardingView({
|
||||
modalModel: modalModel,
|
||||
userModel: userModel,
|
||||
editorModel: editorModel,
|
||||
model: model,
|
||||
visDefinitionModel: visDefinitionModel
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
module.exports = launcher;
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
var LocalStorage = require('builder/components/local-storage/local-storage');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var template = require('./analysis-view.tpl');
|
||||
var Analyses = require('builder/data/analyses');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var BASE_STORAGE_KEY = 'onboarding';
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'modalModel',
|
||||
'userModel',
|
||||
'editorModel',
|
||||
'visDefinitionModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
className: 'AnalysisCompletionDetails is-opening',
|
||||
|
||||
events: {
|
||||
'click .js-close': '_close',
|
||||
'click .js-style': '_onStyle'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
var storageKey = BASE_STORAGE_KEY + '.' + this._visDefinitionModel.get('id');
|
||||
|
||||
LocalStorage.init(storageKey, {
|
||||
userModel: this._userModel
|
||||
});
|
||||
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.html(template({
|
||||
type: this._getGenericAnalysisType()
|
||||
}));
|
||||
|
||||
var onboardingTemplate = this._typeDef().onboardingTemplate;
|
||||
var html = onboardingTemplate && onboardingTemplate(this.model.attributes);
|
||||
this.$('.js-content').html(html);
|
||||
|
||||
this._onChangeEditorModelEdition(this._editorModel);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this.model, 'destroy', this._close);
|
||||
this.listenTo(this._editorModel, 'change:edition', this._onChangeEditorModelEdition);
|
||||
this.add_related_model(this._editorModel);
|
||||
},
|
||||
|
||||
_onChangeEditorModelEdition: function (mdl) {
|
||||
var isEditing = !!mdl.get('edition');
|
||||
this.$el.toggleClass('is-editing', isEditing);
|
||||
},
|
||||
|
||||
_close: function () {
|
||||
this._forget();
|
||||
this.trigger('close', this);
|
||||
},
|
||||
|
||||
_onStyle: function () {
|
||||
this._forget();
|
||||
this.trigger('customEvent', 'style', this);
|
||||
},
|
||||
|
||||
_forget: function () {
|
||||
LocalStorage.set(this._getGenericAnalysisType(), true);
|
||||
},
|
||||
|
||||
_typeDef: function (type) {
|
||||
type = type || this.model.get('type');
|
||||
return Analyses.getAnalysisByType(type);
|
||||
},
|
||||
|
||||
_getGenericAnalysisType: function () {
|
||||
var typeDef = this._typeDef();
|
||||
return typeDef && typeDef.genericType || this.model.get('type');
|
||||
}
|
||||
});
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<div class="Onboarding-fake"></div>
|
||||
<div class="Onboarding-contentWrapper">
|
||||
<div class="Onboarding-body">
|
||||
<p class="CDB-Text Onboarding-headerTitle"><%- _t('analyses-onboarding.' + type + '.title') %></p>
|
||||
<p class="CDB-Text Onboarding-headerText"><%- _t('analyses-onboarding.finished') %></p>
|
||||
|
||||
<div class="js-content"></div>
|
||||
|
||||
<div class="Onboarding-footer">
|
||||
<div class="Onboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('analyses-onboarding.done') %></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-style">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('analyses-onboarding.style-analysis') %></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var template = require('./builder-view.tpl');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
var GAPusher = require('builder/helpers/ga-pusher');
|
||||
|
||||
var BUILDER_KEY = 'onboarding';
|
||||
|
||||
var LEFT_KEY_CODE = 37;
|
||||
var RIGHT_KEY_CODE = 39;
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'userModel',
|
||||
'onboardingNotification',
|
||||
'editorModel'
|
||||
];
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
className: 'BuilderOnboarding is-step0 is-opening',
|
||||
|
||||
events: {
|
||||
'click .js-start': '_onClickNext',
|
||||
'click .js-next': '_onClickNext',
|
||||
'click .js-close': '_close'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
this._initModels();
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.html(template({
|
||||
name: this._userModel.get('name') || this._userModel.get('username')
|
||||
}));
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_initModels: function () {
|
||||
this.model = new Backbone.Model({
|
||||
step: 0
|
||||
});
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this._keyDown = this._onKeyDown.bind(this);
|
||||
$(document).on('keydown', this._keyDown);
|
||||
|
||||
this.listenTo(this.model, 'change:step', this._onChangeStep);
|
||||
this.listenTo(this.model, 'destroy', this._close);
|
||||
this.listenTo(this._editorModel, 'change:edition', this._changeEdition);
|
||||
},
|
||||
|
||||
_changeEdition: function (mdl) {
|
||||
var isEditing = !!mdl.get('edition');
|
||||
this.$el.toggleClass('is-editing', isEditing);
|
||||
},
|
||||
|
||||
_prev: function () {
|
||||
if (this._currentStep() >= 1) {
|
||||
this.model.set('step', this._currentStep() - 1);
|
||||
}
|
||||
},
|
||||
|
||||
_next: function () {
|
||||
if (this._currentStep() <= 3) {
|
||||
this.model.set('step', this._currentStep() + 1);
|
||||
}
|
||||
},
|
||||
|
||||
_currentStep: function () {
|
||||
return this.model.get('step');
|
||||
},
|
||||
|
||||
_onClickNext: function () {
|
||||
this._next();
|
||||
},
|
||||
|
||||
_onChangeStep: function () {
|
||||
var self = this;
|
||||
|
||||
this.$el.removeClass('is-step' + this.model.previous('step'), function () {
|
||||
self.$el.addClass('is-step' + self._currentStep());
|
||||
});
|
||||
|
||||
this.$('.js-step').removeClass('is-step' + this.model.previous('step'), function () {
|
||||
self.$('.js-step').addClass('is-step' + self._currentStep());
|
||||
});
|
||||
},
|
||||
|
||||
_close: function () {
|
||||
this._forget();
|
||||
|
||||
GAPusher({
|
||||
eventName: 'send',
|
||||
hitType: 'event',
|
||||
eventCategory: 'Edit your Map',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Builder'
|
||||
});
|
||||
|
||||
this.trigger('close', this);
|
||||
},
|
||||
|
||||
_onKeyDown: function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if (e.which === LEFT_KEY_CODE) {
|
||||
this._prev();
|
||||
} else if (e.which === RIGHT_KEY_CODE) {
|
||||
this._next();
|
||||
}
|
||||
},
|
||||
|
||||
_forget: function () {
|
||||
this._onboardingNotification.setKey(BUILDER_KEY, true);
|
||||
this._onboardingNotification.save();
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
$(document).off('keydown', this._keyDown);
|
||||
CoreView.prototype.clean.apply(this);
|
||||
}
|
||||
});
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
<div class="BuilderOnboarding-pad"></div>
|
||||
<div class="BuilderOnboarding-pad2"></div>
|
||||
<div class="BuilderOnboarding-contentWrapper is-step0 js-step">
|
||||
<div class="BuilderOnboarding-body">
|
||||
<div class="BuilderOnboarding-header is-step0">
|
||||
<p class="CDB-Text Onboarding-headerTitle"><%- _t('builder-onboarding.title')%></p>
|
||||
<p class="CDB-Text Onboarding-headerText"><%- name %></p>
|
||||
|
||||
<p class="CDB-Text BuilderOnboarding-description">
|
||||
<%- _t('builder-onboarding.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-footer is-step0">
|
||||
<div class="BuilderOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-start">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('builder-onboarding.take-tour')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close track-onboarding--editMap">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('builder-onboarding.edit-map')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-step is-step1">
|
||||
<p class="CDB-Text Onboarding-headerTitle">1/4</p>
|
||||
<p class="CDB-Text Onboarding-headerText"><%- _t('builder-onboarding.toolbar.title')%></p>
|
||||
<p class="CDB-Text BuilderOnboarding-description">
|
||||
<%- _t('builder-onboarding.toolbar.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-step is-step2">
|
||||
<p class="CDB-Text Onboarding-headerTitle">2/4</p>
|
||||
<p class="CDB-Text Onboarding-headerText"><%- _t('builder-onboarding.configurator.title')%></p>
|
||||
<p class="CDB-Text BuilderOnboarding-description">
|
||||
<%- _t('builder-onboarding.configurator.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-step is-step3">
|
||||
<p class="CDB-Text Onboarding-headerTitle">3/4</p>
|
||||
<p class="CDB-Text Onboarding-headerText"><%- _t('builder-onboarding.map.title')%></p>
|
||||
<p class="CDB-Text BuilderOnboarding-description">
|
||||
<%- _t('builder-onboarding.map.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-step is-step4">
|
||||
<p class="CDB-Text Onboarding-headerTitle">4/4</p>
|
||||
<p class="CDB-Text Onboarding-headerText"><%- _t('builder-onboarding.widgets.title')%></p>
|
||||
<p class="CDB-Text BuilderOnboarding-description">
|
||||
<%- _t('builder-onboarding.widgets.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-footer is-step1 is-step2 is-step3">
|
||||
<div class="BuilderOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('builder-onboarding.skip')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-next">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('builder-onboarding.next')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-footer is-step4">
|
||||
<div class="BuilderOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('builder-onboarding.edit-map')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="BuilderOnboarding-pad3"></div>
|
||||
<div class="BuilderOnboarding-pad4"></div>
|
||||
<div class="BuilderOnboarding-pad5"></div>
|
||||
<div class="BuilderOnboarding-shadow"></div>
|
||||
@@ -0,0 +1,31 @@
|
||||
var BuilderOnboardingView = require('./builder-view');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var BUILDER_KEY = 'onboarding';
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'onboardings',
|
||||
'userModel',
|
||||
'onboardingNotification',
|
||||
'editorModel'
|
||||
];
|
||||
|
||||
module.exports = (function () {
|
||||
return {
|
||||
init: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
},
|
||||
|
||||
launch: function () {
|
||||
if (!this._onboardingNotification.getKey(BUILDER_KEY)) {
|
||||
this._onboardings.create(function () {
|
||||
return new BuilderOnboardingView({
|
||||
userModel: this._userModel,
|
||||
editorModel: this._editorModel,
|
||||
onboardingNotification: this._onboardingNotification
|
||||
});
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
var _ = require('underscore');
|
||||
|
||||
var GenericOnboardingLauncher = function (launcherOpts, viewOpts) {
|
||||
var _view;
|
||||
var _onboardingNotification;
|
||||
var _notificationKey;
|
||||
var _onboardings;
|
||||
var _viewOpts;
|
||||
|
||||
if (!launcherOpts || !launcherOpts.view) {
|
||||
throw new Error('view is required');
|
||||
}
|
||||
|
||||
if (!launcherOpts.onboardingNotification) {
|
||||
throw new Error('onboardingNotification is required');
|
||||
}
|
||||
|
||||
if (!launcherOpts.notificationKey) {
|
||||
throw new Error('notificationKey is required');
|
||||
}
|
||||
|
||||
if (!launcherOpts.onboardings) {
|
||||
throw new Error('onboardings is required');
|
||||
}
|
||||
|
||||
if (!viewOpts) {
|
||||
throw new Error('viewOpts is required');
|
||||
}
|
||||
|
||||
_view = launcherOpts.view;
|
||||
_onboardingNotification = launcherOpts.onboardingNotification;
|
||||
_notificationKey = launcherOpts.notificationKey;
|
||||
_onboardings = launcherOpts.onboardings;
|
||||
_viewOpts = viewOpts;
|
||||
|
||||
return {
|
||||
launch: function (launchOpts) {
|
||||
if (!_onboardingNotification.getKey(_notificationKey)) {
|
||||
_onboardings.create(function () {
|
||||
var extendedViewOptions = _.extend(_viewOpts, {
|
||||
onboardingNotification: _onboardingNotification,
|
||||
notificationKey: _notificationKey
|
||||
});
|
||||
return new _view(_.extend(extendedViewOptions, launchOpts));
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = GenericOnboardingLauncher;
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'onboardingNotification',
|
||||
'editorModel',
|
||||
'template',
|
||||
'numberOfSteps',
|
||||
'selector',
|
||||
'modifier',
|
||||
'notificationKey'
|
||||
];
|
||||
|
||||
var LEFT_KEY_CODE = 37;
|
||||
var RIGHT_KEY_CODE = 39;
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
className: 'is-step0 is-opening',
|
||||
|
||||
events: {
|
||||
'click .js-start': '_onClickNext',
|
||||
'click .js-next': '_onClickNext',
|
||||
'click .js-close': '_close',
|
||||
'click .js-highlight': '_close'
|
||||
},
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
this.$el.addClass(this._selector);
|
||||
this.model = new Backbone.Model({
|
||||
step: -1
|
||||
});
|
||||
this._defaultBodyPos = {
|
||||
top: 32,
|
||||
left: 380
|
||||
};
|
||||
|
||||
this._keyDown = this._onKeyDown.bind(this);
|
||||
this._initBinds();
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.$el.addClass(this._selector + this._modifier);
|
||||
this.$el.html(this._template());
|
||||
if (this.model.get('step') === -1) {
|
||||
this._next();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.listenTo(this.model, 'destroy', this._close);
|
||||
this.listenTo(this.model, 'change:step', this._onChangeStep);
|
||||
this.listenTo(this._editorModel, 'change:edition', this._changeEdition);
|
||||
$(document).on('keydown', this._keyDown);
|
||||
},
|
||||
|
||||
_changeEdition: function (mdl) {
|
||||
var isEditing = !!mdl.get('edition');
|
||||
this.$el.toggleClass('is-editing', isEditing);
|
||||
},
|
||||
|
||||
_prev: function () {
|
||||
if (this._currentStep() >= 1) {
|
||||
this.model.set('step', this._currentStep() - 1);
|
||||
}
|
||||
},
|
||||
|
||||
_next: function () {
|
||||
if (this._currentStep() < this._numberOfSteps) {
|
||||
this.model.set('step', this._currentStep() + 1);
|
||||
}
|
||||
},
|
||||
|
||||
_currentStep: function () {
|
||||
return this.model.get('step');
|
||||
},
|
||||
|
||||
_onClickNext: function (event) {
|
||||
if (event) event.stopPropagation();
|
||||
this._next();
|
||||
},
|
||||
|
||||
_onChangeStep: function () {
|
||||
var prev = this.model.previous('step');
|
||||
var step = this.model.get('step');
|
||||
|
||||
this.$el.removeClass('is-step' + prev, function () {
|
||||
this.$el.addClass('is-step' + step);
|
||||
}.bind(this));
|
||||
|
||||
this.$('.js-step').removeClass('is-step' + prev).addClass('is-step' + step);
|
||||
|
||||
this.$('.' + this._selector + '-body').fadeOut(0).delay(200).fadeIn(100);
|
||||
|
||||
this.$('.' + this._selector + '-step.is-step' + prev).css('display', 'none');
|
||||
this.$('.' + this._selector + '-footer.is-step' + prev).css('display', 'none');
|
||||
this.$('.' + this._selector + '-step.is-step' + step).css('display', 'block');
|
||||
this.$('.' + this._selector + '-footer.is-step' + step).css('display', 'block');
|
||||
|
||||
this.$('.' + this._selector + '-contentBody').css('display', step === 0 ? 'block' : 'none');
|
||||
},
|
||||
|
||||
_close: function () {
|
||||
this._forget();
|
||||
this.trigger('close', this);
|
||||
},
|
||||
|
||||
_onKeyDown: function (event) {
|
||||
event.stopPropagation();
|
||||
|
||||
if (event.which === LEFT_KEY_CODE) {
|
||||
this._prev();
|
||||
} else if (event.which === RIGHT_KEY_CODE) {
|
||||
this._next();
|
||||
}
|
||||
},
|
||||
|
||||
_forget: function () {
|
||||
this._onboardingNotification.setKey(this._notificationKey, true);
|
||||
this._onboardingNotification.save();
|
||||
},
|
||||
|
||||
clean: function () {
|
||||
$(document).off('keydown', this._keyDown);
|
||||
CoreView.prototype.clean.apply(this);
|
||||
},
|
||||
|
||||
_setMiddlePad: function (position, padding, body) {
|
||||
var $window = $(window);
|
||||
var $top = this.$('.' + this._selector + '-pads--left .' + this._selector + '-padTop');
|
||||
var $middle = this.$('.' + this._selector + '-pads--left .' + this._selector + '-padMiddle');
|
||||
var $bottom = this.$('.' + this._selector + '-pads--left .' + this._selector + '-padBottom');
|
||||
var vh = $window.height();
|
||||
var vw = $window.width();
|
||||
var isSelector = _.isString(position);
|
||||
var $el = $(position);
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
var left = 0;
|
||||
var top = 0;
|
||||
if ($el.length === 0) return;
|
||||
|
||||
if (isSelector) {
|
||||
width = $el.outerWidth();
|
||||
height = $el.outerHeight();
|
||||
left = $el.offset().left;
|
||||
top = $el.offset().top;
|
||||
} else {
|
||||
width = position.width;
|
||||
height = position.height;
|
||||
left = position.left;
|
||||
top = position.top;
|
||||
}
|
||||
|
||||
// Apply padding
|
||||
var appliedPadding = this._buildPadding(padding);
|
||||
top -= appliedPadding.top;
|
||||
left -= appliedPadding.left;
|
||||
width += appliedPadding.left + appliedPadding.right;
|
||||
height += appliedPadding.top + appliedPadding.bottom;
|
||||
|
||||
// Is it place outside the viewport?
|
||||
if (vw - left > 0 && vw - left < width) {
|
||||
width = vw - left;
|
||||
} else if (vw - left <= 0) {
|
||||
width = 0;
|
||||
}
|
||||
|
||||
// Left offset
|
||||
this.$('.' + this._selector + '-toolbarOverlay').outerWidth(left);
|
||||
|
||||
// Right panel
|
||||
this.$('.' + this._selector + '-contentWrapper').outerWidth(vw - (left + width));
|
||||
|
||||
// Width
|
||||
this.$('.' + this._selector + '-pads--left').outerWidth(width);
|
||||
$top.outerWidth(width);
|
||||
$middle.outerWidth(width);
|
||||
$bottom.outerWidth(width);
|
||||
|
||||
// Height
|
||||
var topHeight = top;
|
||||
var middleHeight = height;
|
||||
var bottomHeight = vh - (topHeight + middleHeight);
|
||||
|
||||
$top.outerHeight(topHeight);
|
||||
$middle.outerHeight(middleHeight);
|
||||
$bottom.outerHeight(bottomHeight);
|
||||
|
||||
// Body text
|
||||
this.$('.' + this._selector + '-body').css('top', body && body.top ? body.top : this._defaultBodyPos.top);
|
||||
this.$('.' + this._selector + '-body').css('left', body && body.left ? body.left : this._defaultBodyPos.left);
|
||||
},
|
||||
|
||||
_buildPadding: function (padding) {
|
||||
var result = {
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
left: 0
|
||||
};
|
||||
|
||||
if (padding) {
|
||||
result.top = this._calculatePadding(padding.top);
|
||||
result.right = this._calculatePadding(padding.right);
|
||||
result.bottom = this._calculatePadding(padding.bottom);
|
||||
result.left = this._calculatePadding(padding.left);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_calculatePadding: function (padding) {
|
||||
return (padding && _.isFinite(padding)) ? padding : 0;
|
||||
}
|
||||
});
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
var _ = require('underscore');
|
||||
var OnboardingView = require('builder/components/onboardings/generic/generic-onboarding-view');
|
||||
var AnalysesService = require('builder/editor/layers/layer-content-views/analyses/analyses-service');
|
||||
var template = require('./analysis-onboarding.tpl');
|
||||
|
||||
module.exports = OnboardingView.extend({
|
||||
events: OnboardingView.extendEvents({
|
||||
'click .js-add-analysis': '_onAddAnalysisClicked'
|
||||
}),
|
||||
|
||||
initialize: function (opts) {
|
||||
OnboardingView.prototype.initialize.call(this, _.extend(opts, {
|
||||
template: template,
|
||||
numberOfSteps: 0,
|
||||
modifier: '--analysis'
|
||||
}));
|
||||
},
|
||||
|
||||
_onAddAnalysisClicked: function () {
|
||||
this._forget();
|
||||
|
||||
this.clean();
|
||||
|
||||
AnalysesService.addAnalysis();
|
||||
},
|
||||
|
||||
_onChangeStep: function () {
|
||||
OnboardingView.prototype._onChangeStep.call(this);
|
||||
|
||||
var step = this.model.get('step');
|
||||
|
||||
if (step === 0) {
|
||||
this._setMiddlePad('.js-editorPanel');
|
||||
}
|
||||
}
|
||||
});
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<div class="LayerOnboarding-toolbarOverlay"></div>
|
||||
|
||||
<div class="LayerOnboarding-pads LayerOnboarding-pads--left">
|
||||
<div class="LayerOnboarding-padTop"></div>
|
||||
<div class="LayerOnboarding-padMiddle js-highlight"></div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-contentWrapper LayerOnboarding-contentWrapper--analysis is-step0 js-step">
|
||||
<div class="LayerOnboarding-contentBody LayerOnboarding-contentBody--analysis is-step0 js-step">
|
||||
<div class="Onboarding-body">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle"><%- _t('analysis-onboarding.title')%></p>
|
||||
|
||||
<p class="CDB-Text Onboarding-headerDescription"><%- _t('analysis-onboarding.description')%></p>
|
||||
|
||||
<ul class="Onboarding-list">
|
||||
<li class="Onboarding-listItem">
|
||||
<p class="CDB-Text LayerOnboarding-description"><%- _t('analysis-onboarding.description-list.item1')%></p>
|
||||
</li>
|
||||
|
||||
<li class="Onboarding-listItem">
|
||||
<p class="CDB-Text LayerOnboarding-description"><%= _t('analysis-onboarding.description-list.item2')%></p>
|
||||
</li>
|
||||
|
||||
<li class="Onboarding-listItem">
|
||||
<p class="CDB-Text LayerOnboarding-description"><%- _t('analysis-onboarding.description-list.item3')%></p>
|
||||
</li>
|
||||
|
||||
<li class="Onboarding-listItem">
|
||||
<p class="CDB-Text LayerOnboarding-description"><%- _t('analysis-onboarding.description-list.item4')%></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('analysis-onboarding.done')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-add-analysis">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('analysis-onboarding.add-analysis')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var OnboardingView = require('builder/components/onboardings/generic/generic-onboarding-view');
|
||||
var template = require('./data-onboarding.tpl');
|
||||
|
||||
module.exports = OnboardingView.extend({
|
||||
initialize: function (opts) {
|
||||
OnboardingView.prototype.initialize.call(this, _.extend(opts, {
|
||||
template: template,
|
||||
numberOfSteps: 4,
|
||||
modifier: '--data'
|
||||
}));
|
||||
},
|
||||
|
||||
_onChangeStep: function () {
|
||||
OnboardingView.prototype._onChangeStep.call(this);
|
||||
|
||||
var step = this.model.get('step');
|
||||
|
||||
if (step === 0) {
|
||||
this._setMiddlePad('.js-editorPanel');
|
||||
} else if (step === 1) {
|
||||
this._setMiddlePad('.js-editorPanelHeader', {top: 16, right: 24, left: 24});
|
||||
} else if (step === 2) {
|
||||
this._setMiddlePad('.js-editorPanelContent', {top: 8, right: 24, left: 24, bottom: -$('.js-optionsBar').outerHeight()});
|
||||
} else if (step === 3) {
|
||||
this._setMiddlePad('.js-optionsBar', null, {top: -190});
|
||||
} else if (step === 4) {
|
||||
var featurePosition = this._getFeatureEditionPosition();
|
||||
this._setMiddlePad(featurePosition, {top: 8, right: 8, bottom: 8, left: 8}, {top: -270, left: -330});
|
||||
}
|
||||
},
|
||||
|
||||
_getFeatureEditionPosition: function () {
|
||||
var $switch = $('.js-mapTableView').first();
|
||||
var $featureEdition = $('.js-newGeometryView').first();
|
||||
var leftOffset = Math.min($switch.length > 0 ? $switch.offset().left : Number.MAX_VALUE, $featureEdition.length > 0 ? $featureEdition.offset().left : Number.MAX_VALUE);
|
||||
var topOffset = Math.min($switch.length > 0 ? $switch.offset().top : Number.MAX_VALUE, $featureEdition.length > 0 ? $featureEdition.offset().top : Number.MAX_VALUE);
|
||||
var rightOffset = Math.max(
|
||||
$switch.length > 0 ? $switch.offset().left + $switch.outerWidth() : Number.MIN_VALUE,
|
||||
$featureEdition.length > 0 ? $featureEdition.offset().left + $featureEdition.outerWidth() : Number.MIN_VALUE
|
||||
);
|
||||
var bottomOffset = Math.max(
|
||||
$switch.length > 0 ? $switch.offset().top + $switch.outerHeight() : Number.MIN_VALUE,
|
||||
$featureEdition.length > 0 ? $featureEdition.offset().top + $featureEdition.outerHeight() : Number.MIN_VALUE
|
||||
);
|
||||
|
||||
return {
|
||||
left: leftOffset,
|
||||
top: topOffset,
|
||||
width: rightOffset - leftOffset,
|
||||
height: bottomOffset - topOffset
|
||||
};
|
||||
}
|
||||
});
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<div class="LayerOnboarding-toolbarOverlay"></div>
|
||||
|
||||
<div class="LayerOnboarding-pads LayerOnboarding-pads--left">
|
||||
<div class="LayerOnboarding-padTop"></div>
|
||||
<div class="LayerOnboarding-padMiddle js-highlight">
|
||||
<div class="LayerOnboarding-body is-step0 js-step">
|
||||
<div class="LayerOnboarding-step is-step1">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">1/4</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('data-onboarding.layer-options.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('data-onboarding.layer-options.description')%>
|
||||
</p>
|
||||
</div>
|
||||
<div class="LayerOnboarding-step is-step2">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">2/4</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('data-onboarding.data-tab.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('data-onboarding.data-tab.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-step is-step3">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">3/4</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('data-onboarding.sql-editor.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('data-onboarding.sql-editor.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-step is-step4">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">4/4</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText is-step4"><%- _t('data-onboarding.add-geometry.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description is-step4">
|
||||
<%- _t('data-onboarding.add-geometry.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step1 is-step2 is-step3">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('data-onboarding.exit')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-next">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('data-onboarding.next')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step4">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('data-onboarding.add-geometry.edit-layer') %></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="LayerOnboarding-padBottom"></div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-contentWrapper is-step0 js-step">
|
||||
<div class="LayerOnboarding-contentBody is-step0 js-step">
|
||||
<div class="LayerOnboarding-header is-step0">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle"><%- _t('data-onboarding.title')%></p>
|
||||
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%= _t('data-onboarding.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step0">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-start">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('data-onboarding.take-tour')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('data-onboarding.edit-layer')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var OnboardingView = require('builder/components/onboardings/generic/generic-onboarding-view');
|
||||
var defaultTemplate = require('./style-onboarding.tpl');
|
||||
var pointsTemplate = require('./style-points-onboarding.tpl');
|
||||
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||||
|
||||
var REQUIRED_OPTS = [
|
||||
'geom'
|
||||
];
|
||||
|
||||
module.exports = OnboardingView.extend({
|
||||
module: 'components/onboardings/layers/style-onboarding/style-onboarding-view',
|
||||
|
||||
initialize: function (opts) {
|
||||
checkAndBuildOpts(opts, REQUIRED_OPTS, this);
|
||||
|
||||
var template = defaultTemplate;
|
||||
var modifier = '--style';
|
||||
var steps = 2;
|
||||
|
||||
if (this._geom === 'point') {
|
||||
template = pointsTemplate;
|
||||
steps = 3;
|
||||
}
|
||||
|
||||
OnboardingView.prototype.initialize.call(this, _.extend(opts, {
|
||||
template: template,
|
||||
numberOfSteps: steps,
|
||||
modifier: modifier
|
||||
}));
|
||||
},
|
||||
|
||||
_onChangeStep: function () {
|
||||
OnboardingView.prototype._onChangeStep.call(this);
|
||||
|
||||
var step = this.model.get('step');
|
||||
|
||||
switch (step) {
|
||||
case 0:
|
||||
this._setMiddlePad('.js-editorPanel');
|
||||
break;
|
||||
case 1:
|
||||
this._setStepOne();
|
||||
break;
|
||||
case 2:
|
||||
this._setStepTwo();
|
||||
break;
|
||||
case 3:
|
||||
this._highlightOptionsBar();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_setStepOne: function () {
|
||||
var $noGeom = $('.js-styleNoGeom');
|
||||
|
||||
if ($noGeom.length > 0) {
|
||||
this._setMiddlePad('.js-styleNoGeom', {top: 8, right: 24, left: 24, bottom: 8});
|
||||
} else if (this._numberOfSteps === 3) {
|
||||
var aggregationInfo = this._getAggregationPositionAndPadding();
|
||||
this._setMiddlePad(aggregationInfo.position, aggregationInfo.padding);
|
||||
} else {
|
||||
this._highlightStyleProperties();
|
||||
}
|
||||
},
|
||||
|
||||
_setStepTwo: function () {
|
||||
if (this._numberOfSteps === 2) {
|
||||
this._highlightOptionsBar();
|
||||
} else {
|
||||
this._highlightStyleProperties();
|
||||
}
|
||||
},
|
||||
|
||||
_highlightStyleProperties: function () {
|
||||
this._setMiddlePad('.js-styleProperties', {top: 8, right: 24, left: 24, bottom: 8});
|
||||
},
|
||||
|
||||
_highlightOptionsBar: function () {
|
||||
this._setMiddlePad('.js-optionsBar', null, {top: -190});
|
||||
},
|
||||
|
||||
_getAggregationPositionAndPadding: function () {
|
||||
var $aggregationTypes = $('.js-aggregationTypes');
|
||||
var $aggregationOptions = $('.js-aggregationOptions');
|
||||
var left = $aggregationTypes.offset().left;
|
||||
var top = $aggregationTypes.offset().top;
|
||||
var width = $aggregationTypes.outerWidth();
|
||||
var height = $aggregationTypes.outerHeight();
|
||||
var bottomPadding = 0;
|
||||
|
||||
if ($aggregationOptions.length > 0) {
|
||||
height += $aggregationOptions.outerHeight();
|
||||
bottomPadding = 8;
|
||||
}
|
||||
|
||||
return {
|
||||
position: {
|
||||
top: top,
|
||||
left: left,
|
||||
width: width,
|
||||
height: height
|
||||
},
|
||||
padding: {
|
||||
top: 8,
|
||||
right: 24,
|
||||
left: 24,
|
||||
bottom: bottomPadding
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
<div class="LayerOnboarding-toolbarOverlay"></div>
|
||||
|
||||
<div class="LayerOnboarding-pads LayerOnboarding-pads--left">
|
||||
<div class="LayerOnboarding-padTop"></div>
|
||||
<div class="LayerOnboarding-padMiddle js-highlight">
|
||||
<div class="LayerOnboarding-body is-step0 js-step">
|
||||
<div class="LayerOnboarding-step is-step1">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">1/2</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('style-onboarding.style.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description LayerOnboarding-description--style">
|
||||
<%- _t('style-onboarding.style.short-description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-step is-step2">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">2/2</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('style-onboarding.cartocss.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('style-onboarding.cartocss.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step1">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.exit')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-next">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.next')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step2">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.style-layer')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="LayerOnboarding-padBottom"></div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-contentWrapper is-step0 js-step">
|
||||
<div class="LayerOnboarding-contentBody is-step0 js-step">
|
||||
<div class="LayerOnboarding-header is-step0">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle"><%- _t('style-onboarding.title')%></p>
|
||||
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('style-onboarding.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step0">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-start">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.take-tour')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.style-layer')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
<div class="LayerOnboarding-toolbarOverlay"></div>
|
||||
|
||||
<div class="LayerOnboarding-pads LayerOnboarding-pads--left">
|
||||
<div class="LayerOnboarding-padTop"></div>
|
||||
<div class="LayerOnboarding-padMiddle js-highlight">
|
||||
<div class="LayerOnboarding-body is-step0 js-step">
|
||||
<div class="LayerOnboarding-step is-step1">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">1/3</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('style-onboarding.aggregation.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('style-onboarding.aggregation.description')%>
|
||||
</p>
|
||||
</div>
|
||||
<div class="LayerOnboarding-step is-step2">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">2/3</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('style-onboarding.style.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description LayerOnboarding-description--style">
|
||||
<%- _t('style-onboarding.style.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-step is-step3">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle">3/3</p>
|
||||
<p class="CDB-Text LayerOnboarding-headerText"><%- _t('style-onboarding.cartocss.title')%></p>
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('style-onboarding.cartocss.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step1 is-step2">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.exit')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-next">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.next')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step3">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.style-layer')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="LayerOnboarding-padBottom"></div>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-contentWrapper is-step0 js-step">
|
||||
<div class="LayerOnboarding-contentBody is-step0 js-step">
|
||||
<div class="LayerOnboarding-header is-step0">
|
||||
<p class="CDB-Text LayerOnboarding-headerTitle"><%- _t('style-onboarding.title')%></p>
|
||||
|
||||
<p class="CDB-Text LayerOnboarding-description">
|
||||
<%- _t('style-onboarding.description')%>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="LayerOnboarding-footer is-step0">
|
||||
<div class="LayerOnboarding-footerButtons">
|
||||
<button class="CDB-Button CDB-Button--secondary CDB-Button--white CDB-Button--big Onboarding-footer--marginRight js-start">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.take-tour')%></span>
|
||||
</button>
|
||||
|
||||
<button class="CDB-Button CDB-Button--primary CDB-Button--big js-close">
|
||||
<span class="CDB-Button-Text CDB-Text u-upperCase is-semibold CDB-Size-medium"><%- _t('style-onboarding.style-layer')%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
var Backbone = require('backbone');
|
||||
var CoreView = require('backbone/core-view');
|
||||
|
||||
/**
|
||||
* View model of a onboarding
|
||||
*/
|
||||
module.exports = Backbone.Model.extend({
|
||||
|
||||
defaults: {
|
||||
show: true,
|
||||
createContentView: function () {
|
||||
return new CoreView();
|
||||
},
|
||||
getContentClasses: function () {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
createContentView: function () {
|
||||
return this.get('createContentView')(this);
|
||||
},
|
||||
|
||||
getContentClasses: function () {
|
||||
return this.get('contentClasses');
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.set('show', true);
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.set('show', false);
|
||||
},
|
||||
|
||||
isHidden: function () {
|
||||
return !this.get('show');
|
||||
},
|
||||
|
||||
/**
|
||||
* @override {Backbone.Model.prototype.destroy}
|
||||
*/
|
||||
destroy: function () {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
this.trigger.apply(this, ['destroy'].concat(args));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
var _ = require('underscore');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var template = require('./onboarding.tpl');
|
||||
|
||||
// Ought to match the duration of the .Dialog.is-closing animation.
|
||||
var CLOSE_DELAY_MS = 120;
|
||||
|
||||
module.exports = CoreView.extend({
|
||||
className: 'Onboarding is-opening',
|
||||
|
||||
initialize: function () {
|
||||
this.listenTo(this.model, 'change:show', this._onShowChange);
|
||||
this.listenTo(this.model, 'destroy', this._onDestroy);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
this.clearSubViews();
|
||||
this.$el.html(template());
|
||||
|
||||
var view = this.model.createContentView();
|
||||
this.$el.addClass(this.model.getContentClasses());
|
||||
this.addView(view);
|
||||
|
||||
view.bind('customEvent', this._onCustomEvent, this);
|
||||
view.bind('close', this._onClose, this);
|
||||
|
||||
view.render();
|
||||
this.$('.js-content').append(view.el);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this.model.show();
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.model.hide();
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
// 'remove' would be a better name ofc, but there is already an internal method with that name in CoreView
|
||||
this.model.destroy();
|
||||
},
|
||||
|
||||
_onShowChange: function (m, show) {
|
||||
if (show) {
|
||||
this.$el.show();
|
||||
this.$el.removeClass('is-closing').addClass('is-opening');
|
||||
} else {
|
||||
this.$el.removeClass('is-opening').addClass('is-closing');
|
||||
this._delayDueToAnimation(function () {
|
||||
this.$el.hide();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_onClose: function () {
|
||||
this.destroy();
|
||||
},
|
||||
|
||||
_onCustomEvent: function (customEventName) {
|
||||
this.destroy();
|
||||
this.trigger('customEvent', customEventName, this);
|
||||
},
|
||||
|
||||
_onDestroy: function () {
|
||||
this.hide();
|
||||
_.invoke(this._subviews, 'allOff');
|
||||
this._delayDueToAnimation(function () {
|
||||
this.clean();
|
||||
});
|
||||
},
|
||||
|
||||
_delayDueToAnimation: function (fn) {
|
||||
setTimeout(fn.bind(this), CLOSE_DELAY_MS);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
<div class="Onboarding js-content"></div>
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var OnboardingView = require('./onboarding-view');
|
||||
var OnboardingViewModel = require('./onboarding-view-model');
|
||||
|
||||
var DESTROYED_ONBOARDING_EVENT = 'destroyedOnboarding';
|
||||
|
||||
/**
|
||||
* Top-level API to handle onboardings.
|
||||
* Is intended to be instantiated and registered in some top-level namespace to be accessibel within the lifecycle of
|
||||
* an client-side application.
|
||||
*
|
||||
* Example:
|
||||
* // In some entry-point:
|
||||
* cdb.onboardings = new OnboardingsServiceModel();
|
||||
*
|
||||
* // Later, in any view, calling create will create a new onboarding viewModel
|
||||
* var onboardingView = cdb.onboardings.create(fn)
|
||||
*
|
||||
* You will probably see the name of "Onboarding" here and there, it's the old nomenclature for the concept of Onboarding.
|
||||
*/
|
||||
module.exports = Backbone.Model.extend({
|
||||
|
||||
/**
|
||||
* Creates a new onboarding view
|
||||
*
|
||||
* @param {Function} createContentView
|
||||
* @return {View} the new onboarding view
|
||||
*/
|
||||
create: function (createContentView, contentClasses) {
|
||||
if (!_.isFunction(createContentView)) throw new Error('createContentView is required');
|
||||
|
||||
if (!this._onboardingView) {
|
||||
this.trigger('willCreateOnboarding');
|
||||
this._onboardingView = this._newOnboardingView();
|
||||
this.trigger('didCreateOnboarding', this._onboardingView);
|
||||
document.body.appendChild(this._onboardingView.el);
|
||||
}
|
||||
|
||||
this._onboardingView.model.set('createContentView', createContentView);
|
||||
this._onboardingView.model.set('contentClasses', contentClasses);
|
||||
this._onboardingView.render();
|
||||
|
||||
return this._onboardingView;
|
||||
},
|
||||
|
||||
/**
|
||||
* Convenience method to add a listener when current onboarding is destroyed
|
||||
*
|
||||
* This is the same as doing
|
||||
* onboardings.create(function (model) {
|
||||
* model.once('destroy', callback, context); // <-- same as onboardings.onDestroyOnce(callback, context);
|
||||
* return new MyView({ … });
|
||||
* });
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @param {Object} [context = undefined]
|
||||
*/
|
||||
onDestroyOnce: function (callback, context) {
|
||||
this.once(DESTROYED_ONBOARDING_EVENT, callback, context);
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
if (this._onboardingView) {
|
||||
this._onboardingView.model.destroy();
|
||||
}
|
||||
},
|
||||
|
||||
_newOnboardingView: function () {
|
||||
var viewModel = new OnboardingViewModel();
|
||||
this._handleBodyClass(viewModel);
|
||||
this._destroyOnEsc(viewModel);
|
||||
|
||||
this.listenToOnce(viewModel, 'destroy', function () {
|
||||
this._onboardingView = null;
|
||||
this.trigger.apply(this, [DESTROYED_ONBOARDING_EVENT].concat(Array.prototype.slice.call(arguments)));
|
||||
this.stopListening(viewModel);
|
||||
});
|
||||
|
||||
var onboardingView = new OnboardingView({
|
||||
model: viewModel
|
||||
});
|
||||
|
||||
onboardingView.bind('customEvent', function (eventName) {
|
||||
this.trigger(eventName);
|
||||
}, this);
|
||||
|
||||
return onboardingView;
|
||||
},
|
||||
|
||||
_destroyOnEsc: function (viewModel) {
|
||||
var destroyOnEsc = function (ev) {
|
||||
if (ev.keyCode === 27) {
|
||||
viewModel.destroy();
|
||||
}
|
||||
};
|
||||
document.addEventListener('keydown', destroyOnEsc);
|
||||
this.listenToOnce(viewModel, 'destroy', function () {
|
||||
document.removeEventListener('keydown', destroyOnEsc);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* TL;DR this method manages document.body class state, to enable scroll inside of an open onboarding.
|
||||
*
|
||||
* Some onboarding content have too much content that can be displayed in the viewport the scroll needs to be enabled.
|
||||
* Since the onboarding is implemented as a fixed positioned element the body needs to be fixated too, for the scroll to
|
||||
* be enabled inside the onboarding instead.
|
||||
*/
|
||||
_handleBodyClass: function (viewModel) {
|
||||
var bodyClass = 'is-inDialog';
|
||||
document.body.classList.add(bodyClass);
|
||||
|
||||
this.listenTo(viewModel, 'change:show', function (m, show) {
|
||||
document.body.classList[show ? 'add' : 'remove'](bodyClass);
|
||||
});
|
||||
|
||||
this.listenToOnce(viewModel, 'destroy', function () {
|
||||
document.body.classList.remove(bodyClass);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user