Adding favorites for Slices and Dashboards

This commit is contained in:
Maxime Beauchemin 2016-03-13 18:16:23 -07:00
parent 5b10b19ed7
commit 7ede732892
10 changed files with 146 additions and 3 deletions

View File

@ -17,6 +17,7 @@ var Dashboard = function (dashboardData) {
filters: {},
init: function () {
this.initDashboardView();
px.initFavStars();
var sliceObjects = [],
dash = this;
dashboard.slices.forEach(function (data) {

View File

@ -117,6 +117,8 @@ function initExploreView() {
$("#collapsed_fieldsets").val(collapsed_fieldsets.join("||"));
}
px.initFavStars();
$('legend').click(function () {
toggle_fieldset($(this), true);
});

View File

@ -132,6 +132,46 @@ var px = (function () {
};
}
function initFavStars() {
var baseUrl = '/dashed/favstar/';
// Init star behavihor for favorite
function show() {
if ($(this).hasClass('selected')) {
$(this).html('<i class="fa fa-star"></i>');
} else {
$(this).html('<i class="fa fa-star-o"></i>');
}
}
$('.favstar')
.attr('title', 'Click to favorite/unfavorite')
.each(show)
.each(function () {
var url = baseUrl + $(this).attr("class_name");
var star = this;
url += '/' + $(this).attr("obj_id") + '/';
$.getJSON(url + 'count/', function (data) {
if (data.count > 0) {
$(star)
.addClass('selected')
.each(show);
}
});
})
.click(function () {
$(this).toggleClass('selected');
var 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();
}
var Slice = function (data, dashboard) {
var timer;
var token = $('#' + data.token);
@ -334,7 +374,8 @@ var px = (function () {
formatDate: formatDate,
timeFormatFactory: timeFormatFactory,
color: color(),
getParam: getParam
getParam: getParam,
initFavStars: initFavStars
};
})();

View File

@ -26,6 +26,12 @@ input.form-control {
margin-left: 365px;
}
.favstar {
margin-right: 10px;
opacity: 0.5;
cursor: pointer;
}
.slice_description{
padding: 8px;
margin: 5px;
@ -84,7 +90,10 @@ form div {
.notbtn {
cursor: default;
box-shadow: none;
border: 1px solid #ccc;
}
hr {
margin-top: 15px;
margin-bottom: 15px;

View File

@ -0,0 +1,30 @@
"""adding favstar model
Revision ID: a2d606a761d9
Revises: 430039611635
Create Date: 2016-03-13 09:56:58.329512
"""
# revision identifiers, used by Alembic.
revision = 'a2d606a761d9'
down_revision = '18e88e1cc004'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table('favstar',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('class_name', sa.String(length=50), nullable=True),
sa.Column('obj_id', sa.Integer(), nullable=True),
sa.Column('dttm', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['ab_user.id'], ),
sa.PrimaryKeyConstraint('id')
)
def downgrade():
op.drop_table('favstar')

View File

@ -0,0 +1,22 @@
"""empty message
Revision ID: d2424a248d63
Revises: ('a2d606a761d9', '836c0bf75904')
Create Date: 2016-03-22 23:25:02.903273
"""
# revision identifiers, used by Alembic.
revision = 'd2424a248d63'
down_revision = ('a2d606a761d9', '836c0bf75904')
from alembic import op
import sqlalchemy as sa
def upgrade():
pass
def downgrade():
pass

View File

@ -1204,3 +1204,13 @@ class DruidColumn(Model):
if not m:
session.add(metric)
session.commit()
class FavStar(Model):
__tablename__ = 'favstar'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('ab_user.id'))
class_name = Column(String(50))
obj_id = Column(Integer)
dttm = Column(DateTime, default=func.now())

View File

@ -43,6 +43,7 @@
<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>

View File

@ -42,7 +42,9 @@
</span>
<span>{{ form.get_field("viz_type")(class_="select2") }}</span>
{% if slice %}
<span class="alert alert-info" title="Slice" data-toggle="tooltip">{{ slice.slice_name }}
<span class="btn btn-default notbtn" title="Slice" data-toggle="tooltip">
<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 Slice metadata">
{% if slice.description %}
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ slice.description }}"></i>

View File

@ -6,7 +6,8 @@ import logging
import re
import traceback
from flask import request, redirect, flash, Response, render_template, Markup
from flask import (
g, request, redirect, flash, Response, render_template, Markup)
from flask.ext.appbuilder import ModelView, CompactCRUDMixin, BaseView, expose
from flask.ext.appbuilder.actions import action
from flask.ext.appbuilder.models.sqla.interface import SQLAInterface
@ -559,6 +560,30 @@ class Dashed(BaseView):
status=500,
mimetype="application/json")
@expose("/favstar/<class_name>/<obj_id>/<action>/")
def favstar(self, class_name, obj_id, action):
session = db.session()
FavStar = models.FavStar
count = 0
favs = session.query(FavStar).filter_by(
class_name=class_name, obj_id=obj_id, user_id=g.user.id).all()
if action == 'select':
if not favs:
session.add(
FavStar(
class_name=class_name, obj_id=obj_id, user_id=g.user.id,
dttm=datetime.now()))
count = 1
elif action == 'unselect':
for fav in favs:
session.delete(fav)
else:
count = len(favs)
session.commit()
return Response(
json.dumps({'count': count}),
mimetype="application/json")
@has_access
@expose("/dashboard/<dashboard_id>/")
def dashboard(self, dashboard_id):