mirror of
https://github.com/apache/superset.git
synced 2024-09-12 08:39:45 -04:00
Fixing explore actions & slice controller interactions (#1292)
* Fixing explore actions & slice controller interactions * Addressing a comment
This commit is contained in:
parent
382b8e85da
commit
3384e7598e
@ -3,7 +3,7 @@ const jQuery = window.jQuery = require('jquery'); // eslint-disable-line
|
|||||||
const px = require('../modules/caravel.js');
|
const px = require('../modules/caravel.js');
|
||||||
const d3 = require('d3');
|
const d3 = require('d3');
|
||||||
const urlLib = require('url');
|
const urlLib = require('url');
|
||||||
const showModal = require('../modules/utils.js').showModal;
|
const utils = require('../modules/utils.js');
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
@ -41,7 +41,8 @@ function injectCss(className, css) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function dashboardContainer(dashboardData) {
|
function dashboardContainer(dashboardData) {
|
||||||
let dashboard = $.extend(dashboardData, {
|
let dashboard = Object.assign({}, utils.controllerInterface, dashboardData, {
|
||||||
|
type: 'dashboard',
|
||||||
filters: {},
|
filters: {},
|
||||||
init() {
|
init() {
|
||||||
this.initDashboardView();
|
this.initDashboardView();
|
||||||
@ -82,6 +83,23 @@ function dashboardContainer(dashboardData) {
|
|||||||
setFilter(sliceId, col, vals, refresh) {
|
setFilter(sliceId, col, vals, refresh) {
|
||||||
this.addFilter(sliceId, col, vals, false, refresh);
|
this.addFilter(sliceId, col, vals, false, refresh);
|
||||||
},
|
},
|
||||||
|
done(slice) {
|
||||||
|
const refresh = slice.getWidgetHeader().find('.refresh');
|
||||||
|
const data = slice.data;
|
||||||
|
if (data !== undefined && data.is_cached) {
|
||||||
|
refresh
|
||||||
|
.addClass('danger')
|
||||||
|
.attr('title',
|
||||||
|
'Served from data cached at ' + data.cached_dttm +
|
||||||
|
'. Click to force refresh')
|
||||||
|
.tooltip('fixTitle');
|
||||||
|
} else {
|
||||||
|
refresh
|
||||||
|
.removeClass('danger')
|
||||||
|
.attr('title', 'Click to force refresh')
|
||||||
|
.tooltip('fixTitle');
|
||||||
|
}
|
||||||
|
},
|
||||||
effectiveExtraFilters(sliceId) {
|
effectiveExtraFilters(sliceId) {
|
||||||
// Summarized filter, not defined by sliceId
|
// Summarized filter, not defined by sliceId
|
||||||
// returns k=field, v=array of values
|
// returns k=field, v=array of values
|
||||||
@ -250,7 +268,7 @@ function dashboardContainer(dashboardData) {
|
|||||||
},
|
},
|
||||||
error(error) {
|
error(error) {
|
||||||
const errorMsg = getAjaxErrorMsg(error);
|
const errorMsg = getAjaxErrorMsg(error);
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
body: 'Sorry, there was an error adding slices to this dashboard: </ br>' + errorMsg,
|
body: 'Sorry, there was an error adding slices to this dashboard: </ br>' + errorMsg,
|
||||||
});
|
});
|
||||||
@ -279,14 +297,14 @@ function dashboardContainer(dashboardData) {
|
|||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
},
|
},
|
||||||
success() {
|
success() {
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: 'Success',
|
title: 'Success',
|
||||||
body: 'This dashboard was saved successfully.',
|
body: 'This dashboard was saved successfully.',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
error(error) {
|
error(error) {
|
||||||
const errorMsg = this.getAjaxErrorMsg(error);
|
const errorMsg = this.getAjaxErrorMsg(error);
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
body: 'Sorry, there was an error saving this dashboard: </ br>' + errorMsg,
|
body: 'Sorry, there was an error saving this dashboard: </ br>' + errorMsg,
|
||||||
});
|
});
|
||||||
@ -344,7 +362,7 @@ function dashboardContainer(dashboardData) {
|
|||||||
injectCss('dashboard-template', css);
|
injectCss('dashboard-template', css);
|
||||||
});
|
});
|
||||||
$('#filters').click(() => {
|
$('#filters').click(() => {
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: '<span class="fa fa-info-circle"></span> Current Global Filters',
|
title: '<span class="fa fa-info-circle"></span> Current Global Filters',
|
||||||
body: 'The following global filters are currently applied:<br/>' +
|
body: 'The following global filters are currently applied:<br/>' +
|
||||||
dashboard.readFilters(),
|
dashboard.readFilters(),
|
||||||
|
@ -12,7 +12,6 @@ export default class EmbedCodeButton extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
height: '400',
|
height: '400',
|
||||||
width: '600',
|
width: '600',
|
||||||
srcLink: window.location.origin + props.slice.data.standalone_endpoint,
|
|
||||||
};
|
};
|
||||||
this.handleInputChange = this.handleInputChange.bind(this);
|
this.handleInputChange = this.handleInputChange.bind(this);
|
||||||
}
|
}
|
||||||
@ -26,11 +25,15 @@ export default class EmbedCodeButton extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generateEmbedHTML() {
|
generateEmbedHTML() {
|
||||||
const { width, height, srcLink } = this.state;
|
const srcLink = window.location.origin + this.props.slice.data.standalone_endpoint;
|
||||||
/* eslint max-len: 0 */
|
/* eslint max-len: 0 */
|
||||||
const embedHTML =
|
return `
|
||||||
`<iframe src="${srcLink}" width="${width}" height="${height}" seamless frameBorder="0" scrolling="no"></iframe>`;
|
<iframe
|
||||||
return embedHTML;
|
src="${srcLink}"
|
||||||
|
width="${this.state.width}"
|
||||||
|
height="${this.state.height}"
|
||||||
|
seamless frameBorder="0" scrolling="no">
|
||||||
|
</iframe>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPopover() {
|
renderPopover() {
|
||||||
|
@ -13,7 +13,6 @@ export default function ExploreActionButtons({ canDownload, slice }) {
|
|||||||
const exportToCSVClasses = cx('btn btn-default btn-sm', {
|
const exportToCSVClasses = cx('btn btn-default btn-sm', {
|
||||||
'disabled disabledButton': !canDownload,
|
'disabled disabledButton': !canDownload,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="btn-group results" role="group">
|
<div className="btn-group results" role="group">
|
||||||
<URLShortLinkButton slice={slice} />
|
<URLShortLinkButton slice={slice} />
|
||||||
|
@ -13,8 +13,6 @@ export default class URLShortLinkButton extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
shortUrl: '',
|
shortUrl: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getShortUrl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getShortUrl() {
|
getShortUrl() {
|
||||||
@ -22,7 +20,7 @@ export default class URLShortLinkButton extends React.Component {
|
|||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/r/shortner/',
|
url: '/r/shortner/',
|
||||||
data: {
|
data: {
|
||||||
data: '/' + window.location.pathname + this.props.slice.querystring(),
|
data: '/' + window.location.pathname + window.location.search,
|
||||||
},
|
},
|
||||||
success: (data) => {
|
success: (data) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -51,16 +49,15 @@ export default class URLShortLinkButton extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const shortUrl = this.state.shortUrl;
|
|
||||||
const isDisabled = shortUrl === '';
|
|
||||||
return (
|
return (
|
||||||
<OverlayTrigger
|
<OverlayTrigger
|
||||||
trigger="click"
|
trigger="click"
|
||||||
rootClose
|
rootClose
|
||||||
placement="left"
|
placement="left"
|
||||||
|
onEnter={this.getShortUrl.bind(this)}
|
||||||
overlay={this.renderPopover()}
|
overlay={this.renderPopover()}
|
||||||
>
|
>
|
||||||
<span className="btn btn-default btn-sm" disabled={isDisabled}>
|
<span className="btn btn-default btn-sm">
|
||||||
<i className="fa fa-link"></i>
|
<i className="fa fa-link"></i>
|
||||||
</span>
|
</span>
|
||||||
</OverlayTrigger>
|
</OverlayTrigger>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// js
|
// js
|
||||||
const $ = window.$ = require('jquery');
|
const $ = window.$ = require('jquery');
|
||||||
const px = require('./../modules/caravel.js');
|
const px = require('./../modules/caravel.js');
|
||||||
const showModal = require('./../modules/utils.js').showModal;
|
const utils = require('./../modules/utils.js');
|
||||||
const jQuery = window.jQuery = require('jquery'); // eslint-disable-line
|
const jQuery = window.jQuery = require('jquery'); // eslint-disable-line
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@ -81,7 +81,7 @@ function saveSlice() {
|
|||||||
if (action === 'saveas') {
|
if (action === 'saveas') {
|
||||||
const sliceName = $('input[name=new_slice_name]').val();
|
const sliceName = $('input[name=new_slice_name]').val();
|
||||||
if (sliceName === '') {
|
if (sliceName === '') {
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
body: 'You must pick a name for the new slice',
|
body: 'You must pick a name for the new slice',
|
||||||
});
|
});
|
||||||
@ -91,13 +91,13 @@ function saveSlice() {
|
|||||||
}
|
}
|
||||||
const addToDash = $('input[name=addToDash]:checked').val();
|
const addToDash = $('input[name=addToDash]:checked').val();
|
||||||
if (addToDash === 'existing' && $('#save_to_dashboard_id').val() === '') {
|
if (addToDash === 'existing' && $('#save_to_dashboard_id').val() === '') {
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
body: 'You must pick an existing dashboard',
|
body: 'You must pick an existing dashboard',
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} else if (addToDash === 'new' && $('input[name=new_dashboard_name]').val() === '') {
|
} else if (addToDash === 'new' && $('input[name=new_dashboard_name]').val() === '') {
|
||||||
showModal({
|
utils.showModal({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
body: 'Please enter a name for the new dashboard',
|
body: 'Please enter a name for the new dashboard',
|
||||||
});
|
});
|
||||||
@ -336,16 +336,7 @@ function initExploreView() {
|
|||||||
prepSaveDialog();
|
prepSaveDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
function initComponents() {
|
function renderExploreActions() {
|
||||||
const queryAndSaveBtnsEl = document.getElementById('js-query-and-save-btns');
|
|
||||||
ReactDOM.render(
|
|
||||||
<QueryAndSaveBtns
|
|
||||||
canAdd={queryAndSaveBtnsEl.getAttribute('data-can-add')}
|
|
||||||
onQuery={() => query(true)}
|
|
||||||
/>,
|
|
||||||
queryAndSaveBtnsEl
|
|
||||||
);
|
|
||||||
|
|
||||||
const exploreActionsEl = document.getElementById('js-explore-actions');
|
const exploreActionsEl = document.getElementById('js-explore-actions');
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<ExploreActionButtons
|
<ExploreActionButtons
|
||||||
@ -356,14 +347,49 @@ function initComponents() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initComponents() {
|
||||||
|
const queryAndSaveBtnsEl = document.getElementById('js-query-and-save-btns');
|
||||||
|
ReactDOM.render(
|
||||||
|
<QueryAndSaveBtns
|
||||||
|
canAdd={queryAndSaveBtnsEl.getAttribute('data-can-add')}
|
||||||
|
onQuery={() => query(true)}
|
||||||
|
/>,
|
||||||
|
queryAndSaveBtnsEl
|
||||||
|
);
|
||||||
|
renderExploreActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
let exploreController = {
|
||||||
|
type: 'slice',
|
||||||
|
done: (sliceObj) => {
|
||||||
|
slice = sliceObj;
|
||||||
|
renderExploreActions();
|
||||||
|
const cachedSelector = $('#is_cached');
|
||||||
|
if (slice.data !== undefined && slice.data.is_cached) {
|
||||||
|
cachedSelector
|
||||||
|
.attr(
|
||||||
|
'title',
|
||||||
|
`Served from data cached at ${slice.data.cached_dttm}. Click [Query] to force refresh`)
|
||||||
|
.show()
|
||||||
|
.tooltip('fixTitle');
|
||||||
|
} else {
|
||||||
|
cachedSelector.hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (sliceObj) => {
|
||||||
|
slice = sliceObj;
|
||||||
|
renderExploreActions();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
exploreController = Object.assign({}, utils.controllerInterface, exploreController);
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
const data = $('.slice').data('slice');
|
const data = $('.slice').data('slice');
|
||||||
|
|
||||||
initExploreView();
|
initExploreView();
|
||||||
|
|
||||||
slice = px.Slice(data);
|
slice = px.Slice(data, exploreController);
|
||||||
|
|
||||||
$('.slice').data('slice', slice);
|
|
||||||
|
|
||||||
// call vis render method, which issues ajax
|
// call vis render method, which issues ajax
|
||||||
// calls render on the slice for the first time
|
// calls render on the slice for the first time
|
||||||
|
@ -25,40 +25,41 @@ const px = function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('.favstar')
|
$('.favstar')
|
||||||
.attr('title', 'Click to favorite/unfavorite')
|
.attr('title', 'Click to favorite/unfavorite')
|
||||||
.css('cursor', 'pointer')
|
.css('cursor', 'pointer')
|
||||||
.each(show)
|
.each(show)
|
||||||
.each(function () {
|
.each(function () {
|
||||||
let url = baseUrl + $(this).attr('class_name');
|
let url = baseUrl + $(this).attr('class_name');
|
||||||
const star = this;
|
const star = this;
|
||||||
url += '/' + $(this).attr('obj_id') + '/';
|
url += '/' + $(this).attr('obj_id') + '/';
|
||||||
$.getJSON(url + 'count/', function (data) {
|
$.getJSON(url + 'count/', function (data) {
|
||||||
if (data.count > 0) {
|
if (data.count > 0) {
|
||||||
$(star).addClass('selected').each(show);
|
$(star).addClass('selected').each(show);
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.click(function () {
|
|
||||||
$(this).toggleClass('selected');
|
|
||||||
let url = baseUrl + $(this).attr('class_name');
|
|
||||||
url += '/' + $(this).attr('obj_id') + '/';
|
|
||||||
if ($(this).hasClass('selected')) {
|
|
||||||
url += 'select/';
|
|
||||||
} else {
|
|
||||||
url += 'unselect/';
|
|
||||||
}
|
}
|
||||||
$.get(url);
|
});
|
||||||
$(this).each(show);
|
})
|
||||||
})
|
.click(function () {
|
||||||
|
$(this).toggleClass('selected');
|
||||||
|
let url = baseUrl + $(this).attr('class_name');
|
||||||
|
url += '/' + $(this).attr('obj_id') + '/';
|
||||||
|
if ($(this).hasClass('selected')) {
|
||||||
|
url += 'select/';
|
||||||
|
} else {
|
||||||
|
url += 'unselect/';
|
||||||
|
}
|
||||||
|
$.get(url);
|
||||||
|
$(this).each(show);
|
||||||
|
})
|
||||||
.tooltip();
|
.tooltip();
|
||||||
}
|
}
|
||||||
const Slice = function (data, dashboard) {
|
const Slice = function (data, controller) {
|
||||||
let timer;
|
let timer;
|
||||||
const token = $('#' + data.token);
|
const token = $('#' + data.token);
|
||||||
const containerId = data.token + '_con';
|
const containerId = data.token + '_con';
|
||||||
const selector = '#' + containerId;
|
const selector = '#' + containerId;
|
||||||
const container = $(selector);
|
const container = $(selector);
|
||||||
const sliceId = data.slice_id;
|
const sliceId = data.slice_id;
|
||||||
|
const origJsonEndpoint = data.json_endpoint;
|
||||||
let dttm = 0;
|
let dttm = 0;
|
||||||
const stopwatch = function () {
|
const stopwatch = function () {
|
||||||
dttm += 10;
|
dttm += 10;
|
||||||
@ -76,16 +77,13 @@ const px = function () {
|
|||||||
container,
|
container,
|
||||||
containerId,
|
containerId,
|
||||||
selector,
|
selector,
|
||||||
querystring(params) {
|
querystring() {
|
||||||
const newParams = params || {};
|
|
||||||
const parser = document.createElement('a');
|
const parser = document.createElement('a');
|
||||||
parser.href = data.json_endpoint;
|
parser.href = data.json_endpoint;
|
||||||
if (dashboard !== undefined) {
|
if (controller.type === 'dashboard') {
|
||||||
let flts = '';
|
parser.href = origJsonEndpoint;
|
||||||
if (newParams.extraFilters !== false) {
|
let flts = controller.effectiveExtraFilters(sliceId);
|
||||||
flts = dashboard.effectiveExtraFilters(sliceId);
|
flts = encodeURIComponent(JSON.stringify(flts));
|
||||||
flts = encodeURIComponent(JSON.stringify(flts));
|
|
||||||
}
|
|
||||||
qrystr = parser.search + '&extra_filters=' + flts;
|
qrystr = parser.search + '&extra_filters=' + flts;
|
||||||
} else if ($('#query').length === 0) {
|
} else if ($('#query').length === 0) {
|
||||||
qrystr = parser.search;
|
qrystr = parser.search;
|
||||||
@ -104,11 +102,10 @@ const px = function () {
|
|||||||
};
|
};
|
||||||
return Mustache.render(s, context);
|
return Mustache.render(s, context);
|
||||||
},
|
},
|
||||||
jsonEndpoint(params) {
|
jsonEndpoint() {
|
||||||
const newParams = params || {};
|
|
||||||
const parser = document.createElement('a');
|
const parser = document.createElement('a');
|
||||||
parser.href = data.json_endpoint;
|
parser.href = data.json_endpoint;
|
||||||
let endpoint = parser.pathname + this.querystring({ extraFilters: newParams.extraFilters });
|
let endpoint = parser.pathname + this.querystring();
|
||||||
endpoint += '&json=true';
|
endpoint += '&json=true';
|
||||||
endpoint += '&force=' + this.force;
|
endpoint += '&force=' + this.force;
|
||||||
return endpoint;
|
return endpoint;
|
||||||
@ -116,43 +113,16 @@ const px = function () {
|
|||||||
d3format(col, number) {
|
d3format(col, number) {
|
||||||
// uses the utils memoized d3format function and formats based on
|
// uses the utils memoized d3format function and formats based on
|
||||||
// column level defined preferences
|
// column level defined preferences
|
||||||
const format = this.data.column_formats[col];
|
const format = data.column_formats[col];
|
||||||
return utils.d3format(format, number);
|
return utils.d3format(format, number);
|
||||||
},
|
},
|
||||||
/* eslint no-shadow: 0 */
|
/* eslint no-shadow: 0 */
|
||||||
done(data) {
|
done(payload) {
|
||||||
|
Object.assign(data, payload);
|
||||||
|
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
token.find('img.loading').hide();
|
token.find('img.loading').hide();
|
||||||
container.show();
|
container.show();
|
||||||
let cachedSelector = null;
|
|
||||||
if (dashboard === undefined) {
|
|
||||||
cachedSelector = $('#is_cached');
|
|
||||||
if (data !== undefined && data.is_cached) {
|
|
||||||
cachedSelector
|
|
||||||
.attr(
|
|
||||||
'title',
|
|
||||||
`Served from data cached at ${data.cached_dttm}. Click [Query] to force-refresh`)
|
|
||||||
.show()
|
|
||||||
.tooltip('fixTitle');
|
|
||||||
} else {
|
|
||||||
cachedSelector.hide();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const refresh = this.getWidgetHeader().find('.refresh');
|
|
||||||
if (data !== undefined && data.is_cached) {
|
|
||||||
refresh
|
|
||||||
.addClass('danger')
|
|
||||||
.attr('title',
|
|
||||||
'Served from data cached at ' + data.cached_dttm +
|
|
||||||
'. Click to force-refresh')
|
|
||||||
.tooltip('fixTitle');
|
|
||||||
} else {
|
|
||||||
refresh
|
|
||||||
.removeClass('danger')
|
|
||||||
.attr('title', 'Click to force-refresh')
|
|
||||||
.tooltip('fixTitle');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
slice.viewSqlQuery = data.query;
|
slice.viewSqlQuery = data.query;
|
||||||
@ -162,6 +132,7 @@ const px = function () {
|
|||||||
$('#timer').addClass('label-success');
|
$('#timer').addClass('label-success');
|
||||||
$('.query-and-save button').removeAttr('disabled');
|
$('.query-and-save button').removeAttr('disabled');
|
||||||
always(data);
|
always(data);
|
||||||
|
controller.done(this);
|
||||||
},
|
},
|
||||||
getErrorMsg(xhr) {
|
getErrorMsg(xhr) {
|
||||||
if (xhr.statusText === 'timeout') {
|
if (xhr.statusText === 'timeout') {
|
||||||
@ -193,6 +164,7 @@ const px = function () {
|
|||||||
$('#timer').addClass('btn-danger');
|
$('#timer').addClass('btn-danger');
|
||||||
$('.query-and-save button').removeAttr('disabled');
|
$('.query-and-save button').removeAttr('disabled');
|
||||||
always(data);
|
always(data);
|
||||||
|
controller.error(this);
|
||||||
},
|
},
|
||||||
width() {
|
width() {
|
||||||
return token.width();
|
return token.width();
|
||||||
@ -238,30 +210,19 @@ const px = function () {
|
|||||||
this.viz.resize();
|
this.viz.resize();
|
||||||
},
|
},
|
||||||
addFilter(col, vals) {
|
addFilter(col, vals) {
|
||||||
if (dashboard !== undefined) {
|
controller.addFilter(sliceId, col, vals);
|
||||||
dashboard.addFilter(sliceId, col, vals);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
setFilter(col, vals) {
|
setFilter(col, vals) {
|
||||||
if (dashboard !== undefined) {
|
controller.setFilter(sliceId, col, vals);
|
||||||
dashboard.setFilter(sliceId, col, vals);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
getFilters() {
|
getFilters() {
|
||||||
if (dashboard !== undefined) {
|
return controller.filters[sliceId];
|
||||||
return dashboard.filters[sliceId];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
clearFilter() {
|
clearFilter() {
|
||||||
if (dashboard !== undefined) {
|
controller.clearFilter(sliceId);
|
||||||
dashboard.clearFilter(sliceId);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
removeFilter(col, vals) {
|
removeFilter(col, vals) {
|
||||||
if (dashboard !== undefined) {
|
controller.removeFilter(sliceId, col, vals);
|
||||||
dashboard.removeFilter(sliceId, col, vals);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
slice.viz = vizMap[data.form_data.viz_type](slice);
|
slice.viz = vizMap[data.form_data.viz_type](slice);
|
||||||
|
@ -103,7 +103,23 @@ function d3format(format, number) {
|
|||||||
}
|
}
|
||||||
return formatters[format](number);
|
return formatters[format](number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Slice objects interact with their context through objects that implement
|
||||||
|
// this controllerInterface (dashboard, explore, standalone)
|
||||||
|
const controllerInterface = {
|
||||||
|
type: null,
|
||||||
|
done: () => {},
|
||||||
|
error: () => {},
|
||||||
|
always: () => {},
|
||||||
|
addFiler: () => {},
|
||||||
|
setFilter: () => {},
|
||||||
|
getFilters: () => false,
|
||||||
|
clearFilter: () => {},
|
||||||
|
removeFilter: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
controllerInterface,
|
||||||
d3format,
|
d3format,
|
||||||
fixDataTableBodyHeight,
|
fixDataTableBodyHeight,
|
||||||
showModal,
|
showModal,
|
||||||
|
@ -2,12 +2,16 @@ const $ = window.$ = require('jquery');
|
|||||||
/* eslint no-unused-vars: 0 */
|
/* eslint no-unused-vars: 0 */
|
||||||
const jQuery = window.jQuery = $;
|
const jQuery = window.jQuery = $;
|
||||||
const px = require('./modules/caravel.js');
|
const px = require('./modules/caravel.js');
|
||||||
|
const utils = require('./modules/utils.js');
|
||||||
|
|
||||||
require('bootstrap');
|
require('bootstrap');
|
||||||
|
|
||||||
|
const standaloneController = Object.assign(
|
||||||
|
{}, utils.controllerInterface, { type: 'standalone' });
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
const data = $('.slice').data('slice');
|
const data = $('.slice').data('slice');
|
||||||
const slice = px.Slice(data);
|
const slice = px.Slice(data, standaloneController);
|
||||||
slice.render();
|
slice.render();
|
||||||
slice.bindResizeToWindowResize();
|
slice.bindResizeToWindowResize();
|
||||||
});
|
});
|
||||||
|
@ -31,7 +31,13 @@ describe('EmbedCodeButton', () => {
|
|||||||
width: '2000',
|
width: '2000',
|
||||||
srcLink: 'http://localhost/endpoint_url',
|
srcLink: 'http://localhost/endpoint_url',
|
||||||
});
|
});
|
||||||
const embedHTML = `<iframe src="http://localhost/endpoint_url" width="2000" height="1000" seamless frameBorder="0" scrolling="no"></iframe>`;
|
const embedHTML = `
|
||||||
|
<iframe
|
||||||
|
src="nullendpoint_url"
|
||||||
|
width="2000"
|
||||||
|
height="1000"
|
||||||
|
seamless frameBorder="0" scrolling="no">
|
||||||
|
</iframe>`;
|
||||||
expect(wrapper.instance().generateEmbedHTML()).to.equal(embedHTML);
|
expect(wrapper.instance().generateEmbedHTML()).to.equal(embedHTML);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user