From c97b0b6026f634f16b7cd48bcea23a408878d7dc Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin <maximebeauchemin@gmail.com> Date: Sun, 13 Dec 2015 10:03:06 -0800 Subject: [PATCH] Slightly better layout for explore page --- panoramix/forms.py | 2 + .../versions/55179c7f25c7_sqla_descr.py | 22 +++++ panoramix/models.py | 8 ++ panoramix/static/panoramix.css | 15 +++- panoramix/templates/panoramix/explore.html | 80 +++++++++---------- panoramix/views.py | 4 +- panoramix/viz.py | 18 +---- 7 files changed, 88 insertions(+), 61 deletions(-) create mode 100644 panoramix/migrations/versions/55179c7f25c7_sqla_descr.py diff --git a/panoramix/forms.py b/panoramix/forms.py index cc29ecf64f1a2..f287f5ca03bf0 100644 --- a/panoramix/forms.py +++ b/panoramix/forms.py @@ -339,6 +339,7 @@ class QueryForm(OmgWtForm): slice_name = HiddenField() previous_viz_type = HiddenField(default=viz.viz_type) collapsed_fieldsets = HiddenField() + viz_type = self.field_dict.get('viz_type') filter_cols = datasource.filterable_column_names or [''] for i in range(10): @@ -361,6 +362,7 @@ class QueryForm(OmgWtForm): if s: setattr(QueryForm, s, px_form_fields[s]) + # datasource type specific form elements if datasource.__class__.__name__ == 'SqlaTable': QueryForm.fieldsets += ({ diff --git a/panoramix/migrations/versions/55179c7f25c7_sqla_descr.py b/panoramix/migrations/versions/55179c7f25c7_sqla_descr.py new file mode 100644 index 0000000000000..aade0b930aa0c --- /dev/null +++ b/panoramix/migrations/versions/55179c7f25c7_sqla_descr.py @@ -0,0 +1,22 @@ +"""sqla_descr + +Revision ID: 55179c7f25c7 +Revises: 315b3f4da9b0 +Create Date: 2015-12-13 08:38:43.704145 + +""" + +# revision identifiers, used by Alembic. +revision = '55179c7f25c7' +down_revision = '315b3f4da9b0' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column('tables', sa.Column('description', sa.Text(), nullable=True)) + + +def downgrade(): + op.drop_column('tables', 'description') diff --git a/panoramix/models.py b/panoramix/models.py index f1547a34c7e44..73d060d30c958 100644 --- a/panoramix/models.py +++ b/panoramix/models.py @@ -225,6 +225,7 @@ class SqlaTable(Model, Queryable, AuditMixinNullable): id = Column(Integer, primary_key=True) table_name = Column(String(250), unique=True) main_dttm_col = Column(String(250)) + description = Column(Text) default_endpoint = Column(Text) database_id = Column(Integer, ForeignKey('dbs.id'), nullable=False) database = relationship( @@ -241,6 +242,9 @@ def perm(self): return ( "[{self.database}].[{self.table_name}]" "(id:{self.id})").format(self=self) + @property + def full_name(self): + return "[{self.database}].[{self.table_name}]".format(self=self) @property def dttm_cols(self): @@ -694,6 +698,10 @@ def perm(self): "[{self.cluster_name}].[{self.datasource_name}]" "(id:{self.id})").format(self=self) + @property + def full_name(self): + return "[{self.cluster_name}].[{self.datasource_name}]".format(self=self) + def __repr__(self): return self.datasource_name diff --git a/panoramix/static/panoramix.css b/panoramix/static/panoramix.css index bbdb22b9f17cc..8c4108fec0e84 100644 --- a/panoramix/static/panoramix.css +++ b/panoramix/static/panoramix.css @@ -10,6 +10,19 @@ form div { .navbar-brand a { color: white; } + +.notbtn { + cursor: default; +} + +span.title-block { + background-color: #EEE; + border-radius: 4px; + padding: 6px 12px; + margin: 0px 10px; + font-size: 20px; +} + fieldset.fs-style { font-family: Verdana, Arial, sans-serif; font-size: small; @@ -18,7 +31,7 @@ fieldset.fs-style { background-color: #F4F4F4; border-radius: 6px; padding: 10px; - margin: 10px 0px; + margin: 0px 0px 10px 0px; } legend.legend-style { font-size: 14px; diff --git a/panoramix/templates/panoramix/explore.html b/panoramix/templates/panoramix/explore.html index e3dd9589b152e..811597e6e2f35 100644 --- a/panoramix/templates/panoramix/explore.html +++ b/panoramix/templates/panoramix/explore.html @@ -2,26 +2,44 @@ {% block content_fluid %} {% set datasource = viz.datasource %} {% set form = viz.form %} + +{% macro panofield(fieldname)%} + <div> + {% set field = form.get_field(fieldname)%} + <div> + {{ viz.get_form_override(fieldname, 'label') or field.label }} + {% if field.description %} + <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right" + title="{{ viz.get_form_override(fieldname, 'description') or field.description }}"></i> + {% endif %} + {{ field(class_=form.field_css_classes(field.name)) }} + </div> + </div> +{% endmacro %} + <div class="container-fluid datasource"> - <div class="row"> - <div id="form_container" class="col-md-3"> - <h4> - {{ datasource.name }} + <form id="query" method="GET" style="display: none;"> + <div class="header"> + <a class="btn btn-primary" data-toggle="tooltip" title="Slice!"> + <i class="fa fa-bolt"></i> + </a> + <span class="btn btn-default notbtn"> + <strong>{{ datasource.full_name }}</strong> {% if datasource.description %} <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ datasource.description }}"></i> {% endif %} - <div class="btn-group pull-right" role="group" > - <a class="btn btn-default" href="/{{ datasource.baselink }}/edit/{{ datasource.id }}" data-toggle="tooltip" title="Edit datasource"> + <a class="" href="/{{ datasource.baselink }}/edit/{{ datasource.id }}" data-toggle="tooltip" title="Edit datasource"> <i class="fa fa-edit"></i> </a> - <button type="button" class="btn btn-default druidify" data-toggle="tooltip" title="Slice!"> - <i class="fa fa-bolt"></i> - </button> - </div> - </h4> + </span> + <span class="">{{ form.get_field("viz_type")(class_="select2") }}</span> + <span class="btn btn-info pull-right" + data-toggle="modal" data-target="#query_modal">query</span> + <hr/> + </font> + <div class="row"> + <div id="form_container" class="col-md-3"> - <hr> - <form id="query" method="GET" style="display: none;"> {% for fieldset in form.fieldsets %} <fieldset class="fs-style"> {% if fieldset.label %} @@ -38,30 +56,14 @@ <h4> <div class="fieldset_content"> {% for fieldname in fieldset.fields %} {% if not fieldname.__iter__ %} - <div> - {% set field = form.get_field(fieldname)%} - <div> - {{ viz.get_form_override(fieldname, 'label') or field.label }} - {% if field.description %} - <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right" - title="{{ viz.get_form_override(fieldname, 'description') or field.description }}"></i> - {% endif %} - {{ field(class_=form.field_css_classes(field.name)) }} - </div> - </div> + {{ panofield(fieldname) }} {% else %} <div class="row"> <div class="form-group"> {% for name in fieldname %} <div class="col-xs-{{ (12 / fieldname|length) | int }}"> {% if name %} - {% set field = form.get_field(name)%} - {{ viz.form_overrides.label or field.label }} - {% if field.description %} - <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right" - title="{{ viz.get_form_override(fieldname, 'description') or field.description }}"></i> - {% endif %} - {{ field(class_=form.field_css_classes(field.name)) }} + {{ panofield(name) }} {% endif %} </div> {% endfor %} @@ -90,7 +92,6 @@ <h4> <span class="glyphicon glyphicon-minus" aria-hidden="true"></span> </button> </div> - <hr style="margin: 5px 0px;"/> </div> <div id="filters"></div> <button type="button" id="plus" class="btn btn-sm" aria-label="Add a filter"> @@ -112,7 +113,6 @@ <h4> <i class="fa fa-plus-circle"></i> Save as </button> - <hr style="margin-bottom: 0px;"> <img src="{{ url_for("static", filename="img/tux_panoramix.png") }}" width=250> {{ form.slice_id() }} {{ form.slice_name() }} @@ -122,20 +122,10 @@ <h4> <input type="hidden" name="datasource_id" value="{{ datasource.id }}"> <input type="hidden" name="datasource_type" value="{{ datasource.type }}"> <input type="hidden" name="previous_viz_type" value="{{ viz.viz_type or "table" }}"> - </form><br> + <br> </div> <div class="col-md-9"> - <h4>{{ viz.verbose_name }} - {% if False %} - <span class="label label-success"> - {{ "{0:0.4f}".format(results.duration.total_seconds()) }} s - </span> - {% endif %} - <span class="label pull-right label-info btn" - data-toggle="modal" data-target="#query_modal">query</span> - </h4> - <hr/> {% block messages %} {% endblock %} {% include 'appbuilder/flash.html' %} @@ -175,6 +165,7 @@ <h4 class="modal-title" id="myModalLabel">Query</h4> </div> </div> </div> + </form> </div> {% endblock %} @@ -234,6 +225,7 @@ <h4 class="modal-title" id="myModalLabel">Query</h4> $('legend').click(function () { toggle_fieldset($(this), true); }); + $("#viz_type").change(function() {$("#query").submit();}); collapsed_fieldsets = get_collapsed_fieldsets(); for(var i=0; i<collapsed_fieldsets.length;i++){ toggle_fieldset($('legend:contains("' + collapsed_fieldsets[i] + '")'), false); diff --git a/panoramix/views.py b/panoramix/views.py index 4f679f17e6632..474ce0bb01fa1 100644 --- a/panoramix/views.py +++ b/panoramix/views.py @@ -140,8 +140,8 @@ class TableView(PanoramixModelView, DeleteMixin): list_columns = ['table_link', 'database', 'changed_by', 'changed_on_'] add_columns = ['table_name', 'database', 'default_endpoint', 'offset'] edit_columns = [ - 'table_name', 'database', 'main_dttm_col', 'default_endpoint', - 'offset'] + 'table_name', 'database', 'description', 'main_dttm_col', + 'default_endpoint', 'offset'] related_views = [TableColumnInlineView, SqlMetricInlineView] base_order = ('changed_on','desc') description_columns = { diff --git a/panoramix/viz.py b/panoramix/viz.py index fd0379a42ff15..74a2fa56ef330 100644 --- a/panoramix/viz.py +++ b/panoramix/viz.py @@ -28,7 +28,6 @@ class BaseViz(object): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metrics', 'groupby', @@ -225,7 +224,6 @@ class TableViz(BaseViz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metrics', 'groupby', @@ -268,7 +266,6 @@ class PivotTableViz(BaseViz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'groupby', @@ -324,7 +321,7 @@ class MarkupViz(BaseViz): fieldsets = ( { 'label': None, - 'fields': ('viz_type', 'markup_type', 'code') + 'fields': ('markup_type', 'code') },) is_timeseries = False @@ -350,7 +347,7 @@ class WordCloudViz(BaseViz): { 'label': None, 'fields': ( - 'viz_type', + 'granularity', ('since', 'until'), 'groupby', 'metric', 'limit', ('size_from', 'size_to'), @@ -402,7 +399,6 @@ class BubbleViz(NVD3Viz): { 'label': None, 'fields': ( - 'viz_type', ('since', 'until'), ('series', 'entity'), ('x', 'y'), @@ -477,7 +473,6 @@ class BigNumberViz(BaseViz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metric', @@ -525,7 +520,6 @@ class NVD3TimeSeriesViz(NVD3Viz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metrics', 'groupby', 'limit', @@ -661,7 +655,6 @@ class NVD3TimeSeriesBarViz(NVD3TimeSeriesViz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metrics', 'groupby', 'limit', @@ -678,7 +671,6 @@ class NVD3CompareTimeSeriesViz(NVD3TimeSeriesViz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metrics', 'groupby', 'limit', @@ -696,7 +688,6 @@ class NVD3TimeSeriesStackedViz(NVD3TimeSeriesViz): { 'label': None, 'fields': ( - 'viz_type', 'granularity', ('since', 'until'), 'metrics', 'groupby', 'limit', @@ -714,7 +705,6 @@ class DistributionPieViz(NVD3Viz): { 'label': None, 'fields': ( - 'viz_type', ('since', 'until'), 'metrics', 'groupby', 'limit', @@ -755,7 +745,7 @@ class DistributionBarViz(DistributionPieViz): { 'label': None, 'fields': ( - 'viz_type', 'metrics', 'groupby', + 'metrics', 'groupby', ('since', 'until'), 'limit', ('show_legend', None), @@ -812,7 +802,7 @@ class SunburstViz(BaseViz): { 'label': None, 'fields': ( - 'viz_type', + 'granularity', ('since', 'until'), 'groupby', 'metric', 'secondary_metric',