mirror of
https://github.com/apache/superset.git
synced 2024-09-12 08:39:45 -04:00
Adding favorites for Slices and Dashboards
This commit is contained in:
parent
5b10b19ed7
commit
7ede732892
@ -17,6 +17,7 @@ var Dashboard = function (dashboardData) {
|
|||||||
filters: {},
|
filters: {},
|
||||||
init: function () {
|
init: function () {
|
||||||
this.initDashboardView();
|
this.initDashboardView();
|
||||||
|
px.initFavStars();
|
||||||
var sliceObjects = [],
|
var sliceObjects = [],
|
||||||
dash = this;
|
dash = this;
|
||||||
dashboard.slices.forEach(function (data) {
|
dashboard.slices.forEach(function (data) {
|
||||||
|
@ -117,6 +117,8 @@ function initExploreView() {
|
|||||||
$("#collapsed_fieldsets").val(collapsed_fieldsets.join("||"));
|
$("#collapsed_fieldsets").val(collapsed_fieldsets.join("||"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
px.initFavStars();
|
||||||
|
|
||||||
$('legend').click(function () {
|
$('legend').click(function () {
|
||||||
toggle_fieldset($(this), true);
|
toggle_fieldset($(this), true);
|
||||||
});
|
});
|
||||||
|
@ -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 Slice = function (data, dashboard) {
|
||||||
var timer;
|
var timer;
|
||||||
var token = $('#' + data.token);
|
var token = $('#' + data.token);
|
||||||
@ -334,7 +374,8 @@ var px = (function () {
|
|||||||
formatDate: formatDate,
|
formatDate: formatDate,
|
||||||
timeFormatFactory: timeFormatFactory,
|
timeFormatFactory: timeFormatFactory,
|
||||||
color: color(),
|
color: color(),
|
||||||
getParam: getParam
|
getParam: getParam,
|
||||||
|
initFavStars: initFavStars
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -26,6 +26,12 @@ input.form-control {
|
|||||||
margin-left: 365px;
|
margin-left: 365px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.favstar {
|
||||||
|
margin-right: 10px;
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.slice_description{
|
.slice_description{
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
@ -84,7 +90,10 @@ form div {
|
|||||||
|
|
||||||
.notbtn {
|
.notbtn {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
@ -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')
|
22
dashed/migrations/versions/d2424a248d63_.py
Normal file
22
dashed/migrations/versions/d2424a248d63_.py
Normal 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
|
@ -1204,3 +1204,13 @@ class DruidColumn(Model):
|
|||||||
if not m:
|
if not m:
|
||||||
session.add(metric)
|
session.add(metric)
|
||||||
session.commit()
|
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())
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
<div class="col-md-3"></div>
|
<div class="col-md-3"></div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2>
|
<h2>
|
||||||
|
<span class="favstar" class_name="Dashboard" obj_id="{{ dashboard.id }}"></span>
|
||||||
{{ dashboard.dashboard_title }}
|
{{ dashboard.dashboard_title }}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,7 +42,9 @@
|
|||||||
</span>
|
</span>
|
||||||
<span>{{ form.get_field("viz_type")(class_="select2") }}</span>
|
<span>{{ form.get_field("viz_type")(class_="select2") }}</span>
|
||||||
{% if slice %}
|
{% 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">
|
<a class="" href="/slicemodelview/edit/{{ slice.id }}" data-toggle="tooltip" title="Edit Slice metadata">
|
||||||
{% if slice.description %}
|
{% if slice.description %}
|
||||||
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ slice.description }}"></i>
|
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ slice.description }}"></i>
|
||||||
|
@ -6,7 +6,8 @@ import logging
|
|||||||
import re
|
import re
|
||||||
import traceback
|
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 import ModelView, CompactCRUDMixin, BaseView, expose
|
||||||
from flask.ext.appbuilder.actions import action
|
from flask.ext.appbuilder.actions import action
|
||||||
from flask.ext.appbuilder.models.sqla.interface import SQLAInterface
|
from flask.ext.appbuilder.models.sqla.interface import SQLAInterface
|
||||||
@ -559,6 +560,30 @@ class Dashed(BaseView):
|
|||||||
status=500,
|
status=500,
|
||||||
mimetype="application/json")
|
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
|
@has_access
|
||||||
@expose("/dashboard/<dashboard_id>/")
|
@expose("/dashboard/<dashboard_id>/")
|
||||||
def dashboard(self, dashboard_id):
|
def dashboard(self, dashboard_id):
|
||||||
|
Loading…
Reference in New Issue
Block a user