mirror of https://github.com/apache/superset.git
An airpal like interface
This commit is contained in:
parent
354ef9b4bb
commit
e8ae49d181
4
TODO.md
4
TODO.md
|
@ -11,11 +11,11 @@ List of TODO items for Panoramix
|
||||||
the same way that you can groupby for series, you could chart by. The form fieldset would be common and use
|
the same way that you can groupby for series, you could chart by. The form fieldset would be common and use
|
||||||
a single field to "grid by", a limit number of chart as an N * N grid size.
|
a single field to "grid by", a limit number of chart as an N * N grid size.
|
||||||
* **Free form SQL editor:** Having an Airpal-like easy SQL editor
|
* **Free form SQL editor:** Having an Airpal-like easy SQL editor
|
||||||
* **Advanced dashboard configuration:** define which slices are immune to which filters, how often widgets should refresh,
|
* **Advanced dashboard configuration:** define which slices are immune to which filters, how often widgets should refresh,
|
||||||
maybe this should start as a json blob...
|
maybe this should start as a json blob...
|
||||||
* **Getting proper JS testing:** unit tests on the Python side are pretty solid, but now we need a test
|
* **Getting proper JS testing:** unit tests on the Python side are pretty solid, but now we need a test
|
||||||
suite for the JS part of the site, testing all the ajax-type calls
|
suite for the JS part of the site, testing all the ajax-type calls
|
||||||
* **Annotations layers:** allow for people to maintain data annotations,
|
* **Annotations layers:** allow for people to maintain data annotations,
|
||||||
attached to a layer and time range. These layers can be added on top of some visualizations as annotations.
|
attached to a layer and time range. These layers can be added on top of some visualizations as annotations.
|
||||||
An example of a layer might be "holidays" or "site outages", ...
|
An example of a layer might be "holidays" or "site outages", ...
|
||||||
* **Worth doing? User defined groups:** People could define mappings in the UI of say "Countries I follow" and apply it to different datasets. For now, this is done by writing CASE-WHEN-type expression which is probably good enough.
|
* **Worth doing? User defined groups:** People could define mappings in the UI of say "Countries I follow" and apply it to different datasets. For now, this is done by writing CASE-WHEN-type expression which is probably good enough.
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
{% extends "panoramix/base.html" %}
|
||||||
|
|
||||||
|
{% block head_css %}
|
||||||
|
{{super()}}
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/lib/dataTables/jquery.dataTables.min.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/lib/dataTables/dataTables.bootstrap.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
.topsql {
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
.bordered {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: 1px solid grey;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #EEE;
|
||||||
|
}
|
||||||
|
.metadata {
|
||||||
|
overflow: auto;
|
||||||
|
width: 300px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
.fillup {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.fillheight {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#interactive {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
#results {
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#results table tbody tr td{
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>db: [{{ db }}]</h2>
|
||||||
|
<div class="topsql row">
|
||||||
|
<div class="col-xs-7 fillheight">
|
||||||
|
<textarea id="sql" class="fillup">SELECT * FROM information_schema.tables;
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-5 fillheight">
|
||||||
|
<div class="metadata fillup bordered">
|
||||||
|
Tables
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="interactive">
|
||||||
|
<input type="hidden" id="database_id" value="{{ database_id }}">
|
||||||
|
<button class="btn btn-primary" id="run">Run!</button>
|
||||||
|
<button class="btn btn-default" id="view">Create View</button>
|
||||||
|
</div>
|
||||||
|
<div id="results_section">
|
||||||
|
<hr/>
|
||||||
|
<img id="loading" width="25" style="display: none;" src="/static/img/loading.gif">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div id="results" class="bordered"></div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block tail_js %}
|
||||||
|
{{ super() }}
|
||||||
|
<script src="/static/lib/bootstrap-toggle.min.js"></script>
|
||||||
|
<script src="/static/lib/dataTables/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="/static/lib/dataTables/dataTables.bootstrap.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#run").click(function() {
|
||||||
|
$('#results').hide(0);
|
||||||
|
$('#loading').show(0);
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: '/panoramix/runsql/',
|
||||||
|
data: {
|
||||||
|
'data': JSON.stringify({
|
||||||
|
'database_id': $('#database_id').val(),
|
||||||
|
'sql': $('#sql').val(),
|
||||||
|
})},
|
||||||
|
success: function(data) {
|
||||||
|
$('#loading').hide(0);
|
||||||
|
$('#results').show(0);
|
||||||
|
$('#results').html(data);
|
||||||
|
|
||||||
|
var datatable = $('table').DataTable({
|
||||||
|
paging: false,
|
||||||
|
searching: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
$('#loading').hide(0);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -552,6 +552,38 @@ class Panoramix(BaseView):
|
||||||
templates=templates,
|
templates=templates,
|
||||||
pos_dict=pos_dict)
|
pos_dict=pos_dict)
|
||||||
|
|
||||||
|
@has_access
|
||||||
|
@expose("/sql/<database_id>/")
|
||||||
|
@utils.log_this
|
||||||
|
def sql(self, database_id):
|
||||||
|
mydb = db.session.query(models.Database).filter_by(id=database_id).first()
|
||||||
|
return self.render_template(
|
||||||
|
"panoramix/sql.html",
|
||||||
|
database_id=database_id,
|
||||||
|
db=mydb)
|
||||||
|
|
||||||
|
@has_access
|
||||||
|
@expose("/runsql/", methods=['POST', 'GET'])
|
||||||
|
@utils.log_this
|
||||||
|
def runsql(self):
|
||||||
|
session = db.session()
|
||||||
|
data = json.loads(request.form.get('data'))
|
||||||
|
sql = data.get('sql')
|
||||||
|
database_id = data.get('database_id')
|
||||||
|
mydb = session.query(models.Database).filter_by(id=database_id).first()
|
||||||
|
content = ""
|
||||||
|
if mydb:
|
||||||
|
print("SUPER!")
|
||||||
|
from pandas import read_sql_query
|
||||||
|
eng = mydb.get_sqla_engine()
|
||||||
|
df = read_sql_query(sql=sql, con=eng)
|
||||||
|
content = df.to_html(
|
||||||
|
classes="dataframe table table-striped table-bordered table-condensed")
|
||||||
|
else:
|
||||||
|
print("ELSE")
|
||||||
|
session.commit()
|
||||||
|
return content
|
||||||
|
|
||||||
@has_access
|
@has_access
|
||||||
@expose("/refresh_datasources/")
|
@expose("/refresh_datasources/")
|
||||||
def refresh_datasources(self):
|
def refresh_datasources(self):
|
||||||
|
|
Loading…
Reference in New Issue