ui update (#879)

* caravel ui update

* make headings bold on /explore

* bump back pagination color
This commit is contained in:
Alanna Scott 2016-08-08 10:55:03 -07:00 committed by GitHub
parent cb23362a5b
commit b0a1f07818
19 changed files with 375 additions and 332 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -14,7 +14,7 @@ const ace = require('brace');
require('bootstrap');
require('brace/mode/css');
require('brace/theme/crimson_editor');
require('./main.css');
require('../../stylesheets/dashboard.css');
require('../caravel-select2.js');
// Injects the passed css string into a style sheet with the specified className

View File

@ -11,19 +11,17 @@ function SliceCell({ expandedSlices, removeSlice, slice }) {
<div>
<div className="chart-header">
<div className="row">
<div className="col-md-12 text-center header">
{slice.slice_name}
<div className="col-md-12 header">
<span>{slice.slice_name}</span>
</div>
<div className="col-md-12 chart-controls">
<div className="pull-left">
<div className="pull-right">
<a title="Move chart" data-toggle="tooltip">
<i className="fa fa-arrows drag" />
</a>
<a className="refresh" title="Force refresh data" data-toggle="tooltip">
<i className="fa fa-repeat" />
</a>
</div>
<div className="pull-right">
{slice.description &&
<a title="Toggle chart description">
<i

View File

@ -13,7 +13,7 @@ export default function QueryAndSaveBtns({ canAdd, onQuery }) {
return (
<div className="btn-group query-and-save">
<button type="button" className="btn btn-primary" onClick={onQuery}>
<button type="button" className="btn btn-default" onClick={onQuery}>
<i className="fa fa-bolt"></i>Query
</button>
<button

View File

@ -3,10 +3,10 @@
// nb: to add a new vis, you must also add a Python fn in viz.py
//
// js
var $ = window.$ = require('jquery');
var jQuery = window.jQuery = $;
var px = require('./../modules/caravel.js');
var showModal = require('./../modules/utils.js').showModal;
const $ = window.$ = require('jquery');
const jQuery = window.jQuery = $;
const px = require('./../modules/caravel.js');
const showModal = require('./../modules/utils.js').showModal;
import React from 'react';
import ReactDOM from 'react-dom';
@ -25,21 +25,21 @@ require('../../vendor/pygments.css');
require('../../stylesheets/explore.css');
require('../../node_modules/bootstrap-toggle/css/bootstrap-toggle.min.css');
var slice;
let slice;
var getPanelClass = function (fieldPrefix) {
const getPanelClass = function (fieldPrefix) {
return (fieldPrefix === 'flt' ? 'filter' : 'having') + '_panel';
};
function prepForm() {
// Assigning the right id to form elements in filters
var fixId = function ($filter, fieldPrefix, i) {
const fixId = function ($filter, fieldPrefix, i) {
$filter.attr('id', function () {
return fieldPrefix + '_' + i;
});
['col', 'op', 'eq'].forEach(function (fieldMiddle) {
var fieldName = fieldPrefix + '_' + fieldMiddle;
const fieldName = fieldPrefix + '_' + fieldMiddle;
$filter.find('[id^=' + fieldName + '_]')
.attr('id', function () {
return fieldName + '_' + i;
@ -51,7 +51,7 @@ function prepForm() {
};
['flt', 'having'].forEach(function (fieldPrefix) {
var i = 1;
let i = 1;
$('#' + getPanelClass(fieldPrefix) + ' #filters > div').each(function () {
fixId($(this), fieldPrefix, i);
i++;
@ -59,7 +59,8 @@ function prepForm() {
});
}
function query(force, pushState) {
function query(forceUpdate, pushState) {
let force = forceUpdate;
if (force === undefined) {
force = false;
}
@ -470,29 +471,19 @@ function saveSlice() {
}
$(document).ready(function () {
const data = $('.slice').data('slice');
initExploreView();
// Dynamically register this visualization
var visType = window.viz_type.value;
px.registerViz(visType);
px.registerViz(data.viz_name);
var data = $('.slice').data('slice');
slice = px.Slice(data);
//
$('.slice').data('slice', slice);
// call vis render method, which issues ajax
query(false, false);
// make checkbox inputs display as toggles
$(':checkbox')
.addClass('pull-right')
.attr('data-onstyle', 'default')
.bootstrapToggle({
size: 'mini',
});
$('div.toggle').addClass('pull-right');
slice.bindResizeToWindowResize();
});

View File

@ -68,11 +68,13 @@ $(document).ready(function () {
'#D6E685',
'#1E6823',
],
// Based on github's colors
domain: 'month',
subDomain: 'day',
itemName: 'action',
tooltip: true,
cellSize: 10,
cellPadding: 2,
domainGutter: 22,
});
});
modelViewTable('#dash_table', 'DashboardModelViewAsync', 'changed_on', 'desc');

View File

@ -38,7 +38,6 @@
"autobind-decorator": "^1.3.3",
"bootstrap": "^3.3.6",
"bootstrap-datepicker": "^1.6.0",
"bootstrap-toggle": "^2.2.1",
"brace": "^0.7.0",
"brfs": "^1.4.3",
"cal-heatmap": "3.5.4",

View File

@ -28,6 +28,12 @@ body {
input.form-control {
background-color: white;
}
input.form-control[type=text], input.form-control[type=search] {
border: 1px solid #ccc!important;
box-shadow: none!important;
padding: 2px;
border-radius: 2px;
}
.chart-header a.danger {
color: red;
@ -50,6 +56,8 @@ input.form-control {
margin-right: 10px;
opacity: 0.5;
cursor: pointer;
float: left;
margin-top: 13px;
}
.slice_description{
@ -83,13 +91,6 @@ input[type="checkbox"] {
height: 16px;
float: right;
}
form div {
padding-top: 1px;
}
.header span {
margin-left: 5px;
}
.widget-is-cached {
display: none;
@ -132,9 +133,6 @@ span.title-block {
font-size: 11px !important;
}
div.navbar {
-webkit-box-shadow: 0px 2px 2px #CCC;
-moz-box-shadow: 0px 2px 2px #CCC;
box-shadow: 0px 2px 2px #ccc;
z-index: 999;
}
.panel.panel-primary {
@ -171,10 +169,24 @@ li.widget:hover {
}
div.widget .chart-header {
padding: 5px;
background-color: #f1f1f1;
padding-top: 8px;
background-color: #fff;
color: #333;
border-bottom: 1px solid #aaa;
margin: 0 10px;
}
.chart-header .header-text {
font-size: 20px;
line-height: 22px;
padding-bottom: 8px;
border-bottom: 1px solid #888;
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
}
div.widget .chart-header a {
margin-left: 5px;
}

View File

@ -24,8 +24,8 @@ div.widget .chart-controls {
}
.slice-grid div.widget {
border-radius: 0;
border: 1px solid #ccc;
box-shadow: 2px 1px 5px -2px #aaa;
border: 0px;
box-shadow: none;
background-color: #fff;
overflow: visible;
}
@ -39,9 +39,7 @@ div.widget .chart-controls {
margin: 5px;
position: absolute;
}
.dashboard .title {
text-align: center;
}
.dashboard .slice_title {
text-align: center;
font-weight: bold;
@ -69,7 +67,7 @@ div.widget .chart-controls {
}
.slice-grid div.separator.widget {
border: 1px solid transparent;
border: 1px solid transparent;
box-shadow: none;
z-index: 1;
}
@ -98,3 +96,15 @@ div.widget .chart-controls {
top: 0;
bottom: 0;
}
.dashboard .title {
margin: 0 20px;
}
.dashboard .title .favstar {
font-size: 24px;
}
.chart-header .header {
font-size: 16px;
}

View File

@ -6,13 +6,36 @@
position: absolute;
left: 0;
top: 0;
background-color: #fff;
}
.header hr {
margin-top: 10px;
margin-bottom: 10px;
.slice-name__container {
background-color: #fff;
padding: 16px 20px 20px 20px;
}
.slice-name__text {
color: #333;
font-size: 20px;
border-bottom: 1px solid #aaa;
padding-bottom: 10px;
padding-left: 42px;
font-weight: bold;
}
.edit-slice-description-icon {
float: left;
margin-top: -33px;
margin-left: 20px;
}
.slice-meta {
margin-top: -52px;
}
.navbar {
margin-bottom: 10px;
margin-bottom: 22px;
}
.query-and-save-btns-container {
margin-bottom: 22px;
}

View File

@ -13,10 +13,10 @@
.navbar {
border: none;
.box-shadow(0 1px 2px rgba(0,0,0,.3));
&-brand {
font-size: 24px;
padding: 17px 15px!important;
}
&-inverse {
@ -25,16 +25,17 @@
input[type=text],
input[type=password] {
color: #fff;
.box-shadow(inset 0 -1px 0 @navbar-inverse-link-color);
.placeholder(@navbar-inverse-link-color);
&:focus {
.box-shadow(inset 0 -2px 0 #fff);
}
}
}
}
}
.navbar-inverse .navbar-nav > li > a {
color: #333;
}
// Buttons ====================================================================
@ -56,7 +57,6 @@
background-color: darken(@bg, 12%);
#gradient > .radial(darken(@bg, 12%) 10%, @bg 11%);
background-size: 1000%;
.box-shadow(2px 2px 4px rgba(0,0,0,.4));
}
}
}
@ -68,21 +68,21 @@
#btn(warning,@btn-warning-bg);
#btn(danger,@btn-danger-bg);
#btn(link,#fff);
.btn-group {
padding: 5px;
background-color: #fff;
}
.btn {
text-transform: uppercase;
border: none;
.box-shadow(1px 1px 4px rgba(0,0,0,.4));
.transition(all 0.4s);
&-link {
border-radius: @btn-border-radius-base;
.box-shadow(none);
color: @btn-default-color;
&:hover,
&:focus {
.box-shadow(none);
color: @btn-default-color;
text-decoration: none;
}
@ -169,11 +169,9 @@ input[type=number],
border: none;
border-radius: 0;
-webkit-appearance: none;
.box-shadow(inset 0 -1px 0 #ddd);
font-size: 16px;
&:focus {
.box-shadow(inset 0 -2px 0 @brand-primary);
}
&[disabled],
@ -206,7 +204,6 @@ select.form-control {
background-size: 13px;
background-repeat: no-repeat;
background-position: right center;
.box-shadow(inset 0 -1px 0 #ddd);
font-size: 16px;
line-height: 1.5;
@ -332,7 +329,7 @@ input[type="checkbox"],
height: 18px;
margin-top: -2px;
margin-right: 5px;
border: 2px solid @gray;
border: 1px solid #333;
border-radius: 2px;
.transition(240ms);
}
@ -345,15 +342,15 @@ input[type="checkbox"],
display: table;
width: 6px;
height: 12px;
border: 2px solid #fff;
border: 2px solid #333;
border-top-width: 0;
border-left-width: 0;
.rotate(45deg);
}
&:checked:after {
background-color: @brand-primary;
border-color: @brand-primary;
background-color: #FFFFFF;
border-color: #333;
}
&:disabled:after {
@ -423,12 +420,10 @@ input[type="checkbox"],
background-color: transparent;
border: none;
color: @navbar-default-link-color;
.box-shadow(inset 0 -1px 0 #ddd);
.transition(all 0.2s);
&:hover {
background-color: transparent;
.box-shadow(inset 0 -2px 0 @brand-primary);
color: @brand-primary;
}
}
@ -436,7 +431,6 @@ input[type="checkbox"],
& > li.active > a,
& > li.active > a:focus {
border: none;
.box-shadow(inset 0 -2px 0 @brand-primary);
color: @brand-primary;
&:hover {
@ -446,7 +440,6 @@ input[type="checkbox"],
}
& > li.disabled > a {
.box-shadow(inset 0 -1px 0 #ddd);
}
&.nav-justified {
@ -469,7 +462,6 @@ input[type="checkbox"],
.dropdown-menu {
margin-top: 0;
border: none;
.box-shadow(0 1px 4px rgba(0,0,0,.3));
}
// Indicators =================================================================
@ -597,9 +589,8 @@ input[type="checkbox"],
.panel {
border: none;
border-radius: 2px;
.box-shadow(0 1px 4px rgba(0,0,0,.3));
border-radius: 0;
box-shadow: none;
&-heading {
border-bottom: none;
}
@ -609,9 +600,16 @@ input[type="checkbox"],
}
}
.panel-default > .panel-heading {
color: #333!important;
border-bottom: 1px solid #aaa;
background-color: #fff!important;
margin: 10px;
font-weight: bold;
}
.popover {
border: none;
.box-shadow(0 1px 4px rgba(0,0,0,.3));
}
.carousel {
@ -621,4 +619,3 @@ input[type="checkbox"],
}
}
}

View File

@ -22,15 +22,15 @@
@gray-base: #000;
@gray-darker: lighten(@gray-base, 13.5%); // #222
@gray-dark: #212121;
@gray: #666;
@gray: #333;
@gray-light: #bbb;
@gray-lighter: lighten(@gray-base, 93.5%); // #eee
@brand-primary: @kazan;
@brand-success: darken(@lima, 25%);
@brand-warning: darken(@beach, 10%);
@brand-info: darken(@babu, 10%);
@brand-danger: darken(@rausch, 15%);
@brand-primary: #000;
@brand-success: darken(@lima, 15%);
@brand-info: @beach;
@brand-warning: @hackberry;
@brand-danger: darken(@rausch, 5%);
@default-color: #444;
@default-bg: #fff;
@ -61,7 +61,7 @@
//## Settings for some of the most global styles.
//** Background color for `<body>`.
@body-bg: #fff;
@body-bg: #EDEDED;
//** Global text color on `<body>`.
@text-color: @gray;
@ -83,16 +83,16 @@
@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
@font-family-base: @font-family-sans-serif;
@font-size-base: 13px;
@font-size-large: ceil((@font-size-base * 1.25)); // ~18px
@font-size-small: ceil((@font-size-base * 0.85)); // ~12px
@font-size-base: 12px;
@font-size-large: ceil((@font-size-base * 1.25));
@font-size-small: ceil((@font-size-base * 0.75));
@font-size-h1: 56px;
@font-size-h2: 45px;
@font-size-h3: 34px;
@font-size-h4: 24px;
@font-size-h5: 20px;
@font-size-h6: 14px;
@font-size-h6: 12px;
//** Unit-less `line-height` for use in components like buttons.
@line-height-base: 1.846; // 20/14
@ -101,9 +101,9 @@
//** By default, this inherits from the `<body>`.
@headings-font-family: inherit;
@headings-font-weight: 400;
@headings-font-weight: 900;
@headings-line-height: 1.1;
@headings-color: #444;
@headings-color: #333;
//== Iconography
@ -137,9 +137,9 @@
@line-height-large: 1.3333333; // extra decimals for Win 8.1 Chrome
@line-height-small: 1.5;
@border-radius-base: 3px;
@border-radius-large: 3px;
@border-radius-small: 3px;
@border-radius-base: 2px;
@border-radius-large: 2px;
@border-radius-small: 2px;
//** Global color for active items (e.g., navs or dropdowns).
@component-active-color: #fff;
@ -490,9 +490,9 @@
@pagination-hover-bg: @gray-lighter;
@pagination-hover-border: #ddd;
@pagination-active-color: #fff;
@pagination-active-bg: @brand-primary;
@pagination-active-border: @brand-primary;
@pagination-active-color: #333;
@pagination-active-bg: #fff;
@pagination-active-border: #333;
@pagination-disabled-color: @gray-light;
@pagination-disabled-bg: #fff;
@ -735,7 +735,7 @@
@panel-bg: #fff;
@panel-body-padding: 15px;
@panel-heading-padding: 10px 15px;
@panel-heading-padding: 5px 15px 3px 0px;
@panel-footer-padding: @panel-heading-padding;
@panel-border-radius: @border-radius-base;

View File

@ -19,3 +19,8 @@ input {
.panel-body {
overflow: auto;
}
.cal-heatmap-panel {
padding: 20px;
background-color: #fff;
}

View File

@ -9,12 +9,9 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" style="padding:7px;opacity:0.9;" href="{{appbuilder.get_url_for_index}}">
<img width="50" src="{{ appbuilder.app_icon }}">
<a class="navbar-brand" href="{{appbuilder.get_url_for_index}}">
<img width="75" src="/static/assets/images/caravel.png" style="padding-top:8px;" alt="">
</a>
<span class="navbar-brand">
{{ appbuilder.app_name }}
</span>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">

View File

@ -7,75 +7,77 @@
{% block title %}[dashboard] {{ dashboard.dashboard_title }}{% endblock %}
{% block body %}
<div class="dashboard container-fluid" data-dashboard="{{ dashboard.json_data }}" data-css="{{ dashboard.css }}" data-user="{{ user_id }}">
<div
class="dashboard container-fluid"
data-dashboard="{{ dashboard.json_data }}"
data-css="{{ dashboard.css }}"
data-user="{{ user_id }}"
>
{% include 'caravel/flash_wrapper.html' %}
<!-- Modal -->
<div class="modal fade" id="css_modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content css">
<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" id="myModalLabel">Dashboard CSS</h4>
<h6><strong>Styling applies to this dashboard only</strong></h6>
</div>
<div class="modal-body">
<select id="css_template" class="select2" style="margin-bottom: 5px;">
<option value="" data-css="">CSS template</option>
{% for t in templates %}
<option value="{{ t.id }}" data-css="{{t.css}}">
{{ t.template_name }}
</option>
{% endfor %}
</select><br>
<textarea id="dash_css" rows="30" cols="60">{{ dashboard.css }}</textarea>
<input type="hidden" id="dashboard_id" value="{{ dashboard.id }}" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
<!-- Modal -->
<div class="modal fade" id="css_modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content css">
<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" id="myModalLabel">Dashboard CSS</h4>
<h6><strong>Styling applies to this dashboard only</strong></h6>
</div>
<div class="modal-body">
<select id="css_template" class="select2" style="margin-bottom: 5px;">
<option value="" data-css="">CSS template</option>
{% for t in templates %}
<option value="{{ t.id }}" data-css="{{t.css}}">
{{ t.template_name }}
</option>
{% endfor %}
</select><br>
<textarea id="dash_css" rows="30" cols="60">{{ dashboard.css }}</textarea>
<input type="hidden" id="dashboard_id" value="{{ dashboard.id }}" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="refresh_modal" tabindex="-1" role="dialog">
<div class="modal fade" id="refresh_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" id="myModalLabel">Refresh Interval</h4>
<h6><strong>Choose how frequent should the dashboard refresh</strong></h6>
</div>
<div class="modal-body">
<select id="refresh_dash_interval" class="select2" style="margin-bottom: 5px;">
<option value="0">Don't refresh</option>
<option value="10">10 seconds</option>
<option value="30">30 seconds</option>
<option value="60">1 minute</option>
<option value="300">5 minutes</option>
</select><br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
<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" id="myModalLabel">Refresh Interval</h4>
<h6><strong>Choose how frequent should the dashboard refresh</strong></h6>
</div>
<div class="modal-body">
<select id="refresh_dash_interval" class="select2" style="margin-bottom: 5px;">
<option value="0">Don't refresh</option>
<option value="10">10 seconds</option>
<option value="30">30 seconds</option>
<option value="60">1 minute</option>
<option value="300">5 minutes</option>
</select><br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
<div id="add-slice-container"></div>
<div class="title">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<h2>
<span class="favstar" class_name="Dashboard" obj_id="{{ dashboard.id }}"></span>
{{ dashboard.dashboard_title }}
</h2>
</div>
<div class="col-md-3">
</div>
</div>
<div id="add-slice-container"></div>
<div class="title">
<div class="row">
<div class="col-md-8">
<span class="favstar" class_name="Dashboard" obj_id="{{ dashboard.id }}"></span>
<h2>{{ dashboard.dashboard_title }}</h2>
</div>
<div class="col-md-4">
<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>
@ -101,11 +103,10 @@
</div>
</div>
</div>
</div>
</div>
<!-- gridster class used for backwards compatibility -->
<div id="grid-container" class="slice-grid gridster">
</div>
<!-- gridster class used for backwards compatibility -->
<div id="grid-container" class="slice-grid gridster"></div>
</div>
{% endblock %}

View File

@ -18,7 +18,7 @@
<div>
{{ field.label }}
{% if field.description %}
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right"
<i class="fa fa-question-circle-o" data-toggle="tooltip" data-placement="right"
title="{{ field.description }}"></i>
{% endif %}
{{ field(class_=form.field_css_classes(field.name)) }}
@ -28,37 +28,159 @@
<div class="datasource container-fluid">
<form id="query" method="GET" style="display: none;">
<div class="header">
<span id="js-query-and-save-btns"
data-can-add="{{ can_add }}"
></span>
<div id="form_container" class="col-left-fixed">
<div
id="js-query-and-save-btns"
class="query-and-save-btns-container"
data-can-add="{{ can_add }}"
></div>
<span title="Data Source" data-toggle="tooltip">
<select id="datasource_id" class="select2">
{% for ds in datasources %}
<option url="{{ ds.explore_url }}" {{ "selected" if ds.id == datasource.id }} value="{{ ds.id }}">{{ ds.full_name }}<i class="fa fa-info"></i></option>
{% endfor %}
</select>
</span>
<a href="{{ datasource.url }}" class="btn btn-default-outline" data-toggle="tooltip" title="Edit/configure datasource">
<i class="fa fa-edit"></i>&nbsp;
</a>
<span title="Visualization Type" data-toggle="tooltip">
{{ form.get_field("viz_type")(class_="select2-with-images") }}
</span>
{% if slice %}
<span class="btn btn-default notbtn" title="Slice" data-toggle="tooltip" data-placement="bottom">
<span class="favstar" class_name="Slice" obj_id="{{ slice.id }}"></span>
{{ slice.slice_name }}
<a class="" href="/slicemodelview/edit/{{ slice.id }}" data-toggle="tooltip" title="Edit">
{% if slice.description %}
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ slice.description }}"></i>
<div class="panel panel-default">
<div class="panel-heading">Datasource & Chart Type</div>
<div class="panel-body">
<div>
<!-- DATASOURCE -->
<span title="Data Source" data-toggle="tooltip">
<select id="datasource_id" class="select2">
{% for ds in datasources %}
<option url="{{ ds.explore_url }}" {{ "selected" if ds.id == datasource.id }} value="{{ ds.id }}">{{ ds.full_name }}<i class="fa fa-info"></i></option>
{% endfor %}
</select>
</span>
<a href="{{ datasource.url }}" class="btn btn-default-outline" data-toggle="tooltip" title="Edit/configure datasource">
<i class="fa fa-edit"></i>&nbsp;
</a>
</div>
<br/>
<!-- CHART TYPE -->
<div title="Visualization Type" data-toggle="tooltip">
{{ form.get_field("viz_type")(class_="select2-with-images") }}
</div>
</div>
</div>
{% for fieldset in form.fieldsets %}
<div class="panel panel-default">
{% if fieldset.label %}
<div class="panel-heading">
<span class="legend_label">{{ fieldset.label }}</span>
{% if fieldset.description %}
<i class="fa fa-question-circle-o" data-toggle="tooltip"
data-placement="bottom"
title="{{ fieldset.description }}"></i>
{% endif %}
<i class="fa fa-edit"></i>
</a>
</span>
<!-- <span class="collapser"> [-]</span> -->
</div>
{% endif %}
<div class="panel-body">
{% for fieldname in fieldset.fields %}
{% if not fieldname %}
<hr/>
{% elif fieldname is string %}
{{ panofield(fieldname) }}
{% else %}
<div class="row">
<div class="form-group">
{% for name in fieldname %}
<div class="col-xs-{{ (12 / fieldname|length) | int }}">
{% if name %}
{{ panofield(name) }}
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
<div id="filter_panel" class="panel panel-default">
<div class="panel-heading">
<span class="legend_label">{{ _("Filters") }}</span>
<i class="fa fa-question-circle-o" data-toggle="tooltip"
data-placement="bottom"
title="{{_("Filters are defined using comma delimited strings as in 'US,FR,Other'")}}. {{_("Leave the value field empty to filter empty strings or nulls")}}"></i>
<!--<span class="collapser"> [-]</span>-->
</div>
<div class="panel-body">
<div id="flt0" style="display: none;">
<span class="">{{ form.flt_col_0(class_="form-control inc") }}</span>
<div class="row">
<span class="col col-sm-4">{{ form.flt_op_0(class_="form-control inc") }}</span>
<span class="col col-sm-6">{{ form.flt_eq_0(class_="form-control inc") }}</span>
<button type="button" class="btn btn-default btn-sm remove" aria-label="Delete filter">
<span class="fa fa-minus" aria-hidden="true"></span>
</button>
</div>
</div>
<div id="filters"></div>
<button type="button" id="plus" class="btn btn-default btn-sm" aria-label="Add a filter">
<span class="fa fa-plus" aria-hidden="true"></span>
<span>{{ _("Add filter") }}</span>
</button>
</div>
</div>
{% if form.having_col_0 %}
<div id="having_panel" class="panel panel-default">
<div class="panel-heading">
<span class="legend_label">Result Filters ("having" filters)</span>
<i class="fa fa-info-circle" data-toggle="tooltip"
data-placement="bottom"
title="{{_("The filters to apply after post-aggregation.")}} {{_("Leave the value field empty to filter empty strings or nulls")}}"></i>
<span class="collapser"> [-]</span>
</div>
<div class="panel-body">
<div id="having0" style="display: none;">
<span class="">{{ form.having_col_0(class_="form-control inc") }}</span>
<div class="row">
<span class="col col-sm-4">{{ form.having_op_0(class_="form-control inc") }}</span>
<span class="col col-sm-6">{{ form.having_eq_0(class_="form-control inc") }}</span>
<button type="button"
class="btn btn-default btn-sm remove"
aria-label="Delete filter">
<span class="fa fa-minus"
aria-hidden="true"></span>
</button>
</div>
</div>
<div id="filters"></div>
<button type="button" id="plus"
class="btn btn-default btn-sm"
aria-label="Add a filter">
<span class="fa fa-plus" aria-hidden="true"></span>
<span>Add filter</span>
</button>
</div>
</div>
{% endif %}
<div class="pull-right">
{{ form.slice_id() }}
{{ 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 }}">
<input type="hidden" name="previous_viz_type" value="{{ viz.viz_type or "table" }}">
</div>
<div class="col-offset">
{% block messages %}{% endblock %}
{% include 'appbuilder/flash.html' %}
<div class="slice-name__container">
<span class="favstar" class_name="Slice" obj_id="{{ slice.id }}"></span>
<div class="slice-name__text">{{slice.slice_name}}</div>
<a href="/slicemodelview/edit/{{ slice.id }}" data-toggle="tooltip" title="Edit Description" class="edit-slice-description-icon">
{% if slice.description %}
<i class="fa fa-question-circle-o" data-toggle="tooltip" data-placement="bottom" title="{{ slice.description }}"></i>
{% endif %}
<i class="fa fa-edit"></i>
</a>
<div class="slice-meta pull-right">
<span id="is_cached" class="label label-default" title="{{ _("Force refresh" )}}" data-toggle="tooltip">
cached
</span>
@ -93,132 +215,16 @@
</span>
</div>
</div>
<hr/>
</div>
<div
id="{{ viz.token }}"
class="widget viz slice {{ viz.viz_type }}"
data-slice="{{ viz.json_data }}"
style="height: 700px;">
<img src="{{ url_for("static", filename="assets/images/loading.gif") }}" class="loading" alt="loading">
<div id="{{ viz.token }}_con" class="slice_container" style="height: 100%; width: 100%"></div>
</div>
</div>
<div id="form_container" class="col-left-fixed">
{% for fieldset in form.fieldsets %}
<div class="panel panel-default">
{% if fieldset.label %}
<div class="panel-heading">
<span class="legend_label">{{ fieldset.label }}</span>
{% if fieldset.description %}
<i class="fa fa-info-circle" data-toggle="tooltip"
data-placement="bottom"
title="{{ fieldset.description }}"></i>
{% endif %}
<span class="collapser"> [-]</span>
</div>
{% endif %}
<div class="panel-body">
{% for fieldname in fieldset.fields %}
{% if not fieldname %}
<hr/>
{% elif fieldname is string %}
{{ panofield(fieldname) }}
{% else %}
<div class="row">
<div class="form-group">
{% for name in fieldname %}
<div class="col-xs-{{ (12 / fieldname|length) | int }}">
{% if name %}
{{ panofield(name) }}
{% endif %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
<div id="filter_panel" class="panel panel-default">
<div class="panel-heading">
<span class="legend_label">{{ _("Filters") }}</span>
<i class="fa fa-info-circle" data-toggle="tooltip"
data-placement="bottom"
title="{{_("Filters are defined using comma delimited strings as in 'US,FR,Other'")}}. {{_("Leave the value field empty to filter empty strings or nulls")}}"></i>
<span class="collapser"> [-]</span>
</div>
<div class="panel-body">
<div id="flt0" style="display: none;">
<span class="">{{ form.flt_col_0(class_="form-control inc") }}</span>
<div class="row">
<span class="col col-sm-4">{{ form.flt_op_0(class_="form-control inc") }}</span>
<span class="col col-sm-6">{{ form.flt_eq_0(class_="form-control inc") }}</span>
<button type="button" class="btn btn-default btn-sm remove" aria-label="Delete filter">
<span class="fa fa-minus" aria-hidden="true"></span>
</button>
</div>
</div>
<div id="filters"></div>
<button type="button" id="plus" class="btn btn-default btn-sm" aria-label="Add a filter">
<span class="fa fa-plus" aria-hidden="true"></span>
<span>{{ _("Add filter") }}</span>
</button>
</div>
</div>
{% if form.having_col_0 %}
<div id="having_panel" class="panel panel-default">
<div class="panel-heading">
<span class="legend_label">Result Filters ("having" filters)</span>
<i class="fa fa-info-circle" data-toggle="tooltip"
data-placement="bottom"
title="{{_("The filters to apply after post-aggregation.")}} {{_("Leave the value field empty to filter empty strings or nulls")}}"></i>
<span class="collapser"> [-]</span>
</div>
<div class="panel-body">
<div id="having0" style="display: none;">
<span class="">{{ form.having_col_0(class_="form-control inc") }}</span>
<div class="row">
<span class="col col-sm-4">{{ form.having_op_0(class_="form-control inc") }}</span>
<span class="col col-sm-6">{{ form.having_eq_0(class_="form-control inc") }}</span>
<button type="button"
class="btn btn-default btn-sm remove"
aria-label="Delete filter">
<span class="fa fa-minus"
aria-hidden="true"></span>
</button>
</div>
</div>
<div id="filters"></div>
<button type="button" id="plus"
class="btn btn-default btn-sm"
aria-label="Add a filter">
<span class="fa fa-plus" aria-hidden="true"></span>
<span>Add filter</span>
</button>
</div>
</div>
{% endif %}
{{ form.slice_id() }}
{{ 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 }}">
<input type="hidden" name="previous_viz_type" value="{{ viz.viz_type or "table" }}">
</div>
<div class="col-offset">
{% block messages %}{% endblock %}
{% include 'appbuilder/flash.html' %}
<div
id="{{ viz.token }}"
class="widget viz slice {{ viz.viz_type }}"
data-slice="{{ viz.json_data }}"
style="height: 700px;">
<img src="{{ url_for("static", filename="assets/images/loading.gif") }}" class="loading" alt="loading">
<div id="{{ viz.token }}_con" class="slice_container" style="height: 100%; width: 100%"></div>
</div>
<div class="credits pull-right">{{ "credits: " + viz.credits |safe if viz. credits else "" }}</div>
</div>
<div class="modal fade" id="query_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">

View File

@ -1,15 +1,18 @@
<html>
<head>
<script src="/static/assets/javascripts/dist/css-theme.entry.js"></script>
<script src="/static/assets/javascripts/dist/standalone.entry.js"></script>
<link rel="stylesheet" type="text/css" href="/static/assets/stylesheets/caravel.css" />
<title>{{viz.token}}</title>
<link rel="stylesheet" type="text/css" href="/static/assets/node_modules/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="/static/assets/stylesheets/caravel.css" />
<link rel="stylesheet" type="text/css" href="/static/appbuilder/css/flags/flags16.css" />
<link rel="icon" type="image/png" href="/static/assets/images/favicon.png">
{% set CSS_THEME = appbuilder.get_app.config.get("CSS_THEME") %}
{% set height = request.args.get("height", 700) %}
{% if CSS_THEME %}
<link rel="stylesheet" type="text/css" href="{{ CSS_THEME }}" />
{% endif %}
</head>
<body>
<div
id="{{ viz.token }}"
@ -20,4 +23,7 @@
<div id="{{ viz.token }}_con" class="slice_container" style="height: 100%; width: 100%"></div>
</div>
</body>
<script src="/static/assets/javascripts/dist/css-theme.entry.js"></script>
<script src="/static/assets/javascripts/dist/standalone.entry.js"></script>
</html>

View File

@ -10,12 +10,9 @@
{% block body %}
<div class="container welcome">
{% include 'caravel/flash_wrapper.html' %}
<div class="header">
<h3>{{ _("Welcome!") }}</h3>
<div class="cal-heatmap-panel">
<div id="cal-heatmap"></div>
</div>
<hr/>
<div id="cal-heatmap"></div>
<hr/>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">

View File

@ -605,7 +605,6 @@ class SliceAsync(SliceModelView): # noqa
label_columns = {
'icons': ' ',
'slice_link': _('Slice'),
'viz_type': _('Visualization Type'),
}
appbuilder.add_view_no_menu(SliceAsync)