Skip to content

Commit

Permalink
Saving slices and adding them to dashboards directly from explore view (
Browse files Browse the repository at this point in the history
#680)

* Saving slices from explore view

* Addressing comments
  • Loading branch information
mistercrunch authored Jun 28, 2016
1 parent 7a7f61a commit bd68378
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 72 deletions.
89 changes: 72 additions & 17 deletions caravel/assets/javascripts/explore.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,23 +333,6 @@ function initExploreView() {
$("#having_panel #plus").click(function () {
add_filter(undefined, "having");
});
$("#btn_save").click(function () {
var slice_name = prompt("Name your slice!");
if (slice_name !== "" && slice_name !== null) {
$("#slice_name").val(slice_name);
prepForm();
$("#action").val("save");
$("#query").submit();
}
});
$("#btn_overwrite").click(function () {
var flag = confirm("Overwrite slice [" + $("#slice_name").val() + "] !?");
if (flag) {
$("#action").val("overwrite");
prepForm();
$("#query").submit();
}
});

$(".query").click(function () {
query(true);
Expand Down Expand Up @@ -400,6 +383,78 @@ function initExploreView() {
});
$(this).remove();
});

function prepSaveDialog() {
var setButtonsState = function () {
var add_to_dash = $("input[name=add_to_dash]:checked").val();
if (add_to_dash === 'existing' || add_to_dash === 'new') {
$('.gotodash').removeAttr('disabled');
} else {
$('.gotodash').prop('disabled', true);
}
};
var url = '/dashboardmodelviewasync/api/read';
url += '?_flt_0_owners=' + $('#userid').val();
$.get(url, function (data) {
var choices = [];
for (var i=0; i< data.pks.length; i++) {
choices.push({ id: data.pks[i], text: data.result[i].dashboard_title });
}
$('#save_to_dashboard_id').select2({
data: choices,
dropdownAutoWidth: true
}).on("select2-selecting", function () {
$("#add_to_dash_existing").prop("checked", true);
setButtonsState();
});
});

$("input[name=add_to_dash]").change(setButtonsState);
$("input[name='new_dashboard_name']").on('focus', function () {
$("#add_to_new_dash").prop("checked", true);
setButtonsState();
});
$("input[name='new_slice_name']").on('focus', function () {
$("#save_as_new").prop("checked", true);
setButtonsState();
});
$('#btn_modal_save').click(function () {
var action = $('input[name=rdo_save]:checked').val();
if (action === 'saveas') {
var slice_name = $('input[name=new_slice_name]').val();
if (slice_name === '') {
showModal({
title: "Error",
body: "You must pick a name for the new slice"
});
return;
}
document.getElementById("slice_name").value = slice_name;
}
var add_to_dash = $('input[name=add_to_dash]:checked').val();
if (add_to_dash === 'existing' && $('#save_to_dashboard_id').val() === '') {
showModal({
title: "Error",
body: "You must pick an existing dashboard"
});
return;
} else if (add_to_dash === 'new' && $('input[name=new_dashboard_name]').val() === '') {
showModal({
title: "Error",
body: "Please enter a name for the new dashboard"
});
return;
}
$('#action').val(action);
prepForm();
$("#query").submit();
});
$('#btn_modal_save_goto_dash').click(function () {
document.getElementById("goto_dash").value = 'true';
$('#btn_modal_save').click();
});
}
prepSaveDialog();
}

$(document).ready(function () {
Expand Down
9 changes: 9 additions & 0 deletions caravel/assets/stylesheets/explore.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@
left: 0;
top: 0;
}

.header hr {
margin-top: 10px;
margin-bottom: 10px;
}

.navbar {
margin-bottom: 10px;
}
31 changes: 31 additions & 0 deletions caravel/migrations/versions/27ae655e4247_make_creator_owners.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Make creator owners
Revision ID: 27ae655e4247
Revises: d8bc074f7aad
Create Date: 2016-06-27 08:43:52.592242
"""

# revision identifiers, used by Alembic.
revision = '27ae655e4247'
down_revision = 'd8bc074f7aad'

from alembic import op
from caravel import db, models


def upgrade():
bind = op.get_bind()
session = db.Session(bind=bind)

objects = session.query(models.Slice).all()
objects += session.query(models.Dashboard).all()
for obj in objects:
if obj.created_by and obj.created_by not in obj.owners:
obj.owners.append(obj.created_by)
session.commit()
session.close()


def downgrade():
pass
2 changes: 1 addition & 1 deletion caravel/migrations/versions/960c69cb1f5b_.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

# revision identifiers, used by Alembic.
revision = '960c69cb1f5b'
down_revision = 'd8bc074f7aad'
down_revision = '27ae655e4247'

from alembic import op
import sqlalchemy as sa
Expand Down
42 changes: 22 additions & 20 deletions caravel/templates/caravel/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,26 +75,28 @@ <h2>
</h2>
</div>
<div class="col-md-3">
<div class="btn-group pull-right" role="group" >
<button type="button" id="refresh_dash" class="btn btn-default" data-toggle="tooltip" title="Force refresh the whole dashboard">
<i class="fa fa-refresh"></i>
</button>
<button type="button" id="refresh_dash_periodic" class="btn btn-default" data-toggle="modal" data-target="#refresh_modal">
<i class="fa fa-clock-o" data-toggle="tooltip" title="Decide how frequent should the dashboard refresh"></i>
</button>
<button type="button" id="filters" class="btn btn-default" data-toggle="tooltip" title="View the list of active filters">
<i class="fa fa-filter"></i>
</button>
<button type="button" id="css" class="btn btn-default {{ "disabled disabledButton" if not dash_edit_perm }} " data-toggle="modal" data-target="#css_modal">
<i class="fa fa-css3" data-toggle="tooltip" title="Edit the dashboard's CSS"></i>
</button>
<a id="editdash" class="btn btn-default {{ "disabled disabledButton" if not dash_edit_perm }} " href="/dashboardmodelview/edit/{{ dashboard.id }}" title="Edit this dashboard's property" data-toggle="tooltip" >
<i class="fa fa-edit"></i>
</a>
<button type="button" id="savedash" class="btn btn-default {{ "disabled disabledButton" if not dash_save_perm }}" data-toggle="tooltip" title="Save the current positioning and CSS">
<i class="fa fa-save"></i>
</button>
</div>
{% if dash_edit_perm %}
<div class="btn-group pull-right" role="group" >
<button type="button" id="refresh_dash" class="btn btn-default" data-toggle="tooltip" title="Force refresh the whole dashboard">
<i class="fa fa-refresh"></i>
</button>
<button type="button" id="refresh_dash_periodic" class="btn btn-default" data-toggle="modal" data-target="#refresh_modal">
<i class="fa fa-clock-o" data-toggle="tooltip" title="Decide how frequent should the dashboard refresh"></i>
</button>
<button type="button" id="filters" class="btn btn-default" data-toggle="tooltip" title="View the list of active filters">
<i class="fa fa-filter"></i>
</button>
<button type="button" id="css" class="btn btn-default {{ "disabled disabledButton" if not dash_edit_perm }} " data-toggle="modal" data-target="#css_modal">
<i class="fa fa-css3" data-toggle="tooltip" title="Edit the dashboard's CSS"></i>
</button>
<a id="editdash" class="btn btn-default {{ "disabled disabledButton" if not dash_edit_perm }} " href="/dashboardmodelview/edit/{{ dashboard.id }}" title="Edit this dashboard's property" data-toggle="tooltip" >
<i class="fa fa-edit"></i>
</a>
<button type="button" id="savedash" class="btn btn-default {{ "disabled disabledButton" if not dash_save_perm }}" data-toggle="tooltip" title="Save the current positioning and CSS">
<i class="fa fa-save"></i>
</button>
</div>
{% endif %}
</div>
</div>
</div>
Expand Down
80 changes: 64 additions & 16 deletions caravel/templates/caravel/explore.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@
<div class="datasource container-fluid">
<form id="query" method="GET" style="display: none;">
<div class="header">
<div class="btn-group query-and-save">
<button type="button" class="btn btn-primary query">
<i class="fa fa-bolt"></i>{{ _("Query") }}
</button>
<button
type="button"
id="btn_save"
class="btn btn-default"
{{ "disabled" if not can_add }}
data-target="#save_modal"
data-toggle="modal">
<i class="fa fa-plus-circle"></i>{{ _("Save") }}
</button>
</div>
<span title="Data Source" data-toggle="tooltip">
<select id="datasource_id" class="select2">
{% for ds in datasources %}
Expand Down Expand Up @@ -92,22 +106,6 @@
<hr/>
</div>
<div id="form_container" class="col-left-fixed">
<div class="row center-block">
<div class="btn-group query-and-save">
<button type="button" class="btn btn-primary query">
<i class="fa fa-bolt"></i>{{ _("Query") }}
</button>
{% if viz.form_data.slice_id %}
<button type="button" class="btn btn-default {{ "disabled disabledButton" if not can_edit }}" id="btn_overwrite">
<i class="fa fa-save"></i>{{ _("Overwrite") }}
</button>
{% endif %}
<button type="button" class="btn btn-default {{ "disabled disabledButton" if not can_add }}" id="btn_save">
<i class="fa fa-plus-circle"></i>{{ _("Save as") }}
</button>
</div>
</div>
<br/>
{% for fieldset in form.fieldsets %}
<div class="panel panel-default">
{% if fieldset.label %}
Expand Down Expand Up @@ -210,6 +208,8 @@
{{ form.slice_name() }}
{{ form.collapsed_fieldsets() }}
<input type="hidden" name="action" id="action" value="">
<input type="hidden" name="userid" id="userid" value="{{ userid }}">
<input type="hidden" name="goto_dash" id="goto_dash" value="false">
<input type="hidden" name="datasource_name" value="{{ datasource.name }}">
<input type="hidden" name="datasource_id" value="{{ datasource.id }}">
<input type="hidden" name="datasource_type" value="{{ datasource.type }}">
Expand Down Expand Up @@ -265,6 +265,54 @@ <h4 class="modal-title">{{ _("Datasource Description") }}</h4>
</div>
</div>
</div>
<div class="modal fade" id="save_modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title">{{ _("Save a Slice") }}</h4>
</div>
<div class="modal-body">
{% if slice %}
<input
type="radio"
name="rdo_save"
value="overwrite"
{{ 'disabled' if not can_edit else '' }}
{{ 'checked' if can_edit else '' }}>
Overwrite slice [{{ slice.slice_name }}] <br><br>
{% endif %}
<input
id="save_as_new"
type="radio"
name="rdo_save"
value="saveas"
{{ 'checked' if not slice or not can_edit else '' }}>
Save as
<input type="text" name="new_slice_name" placeholder="[slice name]"><br>
<hr/>
<input type="radio" name="add_to_dash" checked value="false">Do not add to a dashboard<br><br>
<input id="add_to_dash_existing" type="radio" name="add_to_dash" value="existing">Add slice to existing dashboard
<input type="text" id="save_to_dashboard_id" name="save_to_dashboard_id"><br><br>
<input type="radio" id="add_to_new_dash" name="add_to_dash" value="new">Add to new dashboard
<input type="text" name="new_dashboard_name" placeholder="[dashboard name]"> <br><br>
</div>
<div class="modal-footer">
<button type="button" id="btn_modal_save" class="btn btn-primary pull-left">
{{ _("Save") }}
</button>
<button type="button" id="btn_modal_save_goto_dash" class="btn btn-primary pull-left gotodash" disabled>
{{ _("Save & go to dashboard") }}
</button>
<button type="button" class="btn btn-default pull-right" data-dismiss="modal">
{{ _("Cancel") }}
</button>
</div>
</div>
</div>
</div>
</form>
</div>
{% endblock %}
Expand Down
Loading

0 comments on commit bd68378

Please sign in to comment.