Merged in feature/active-dashboard (pull request #15)

Add active field to dashboard
develop
Ensar Sarajcic 2018-10-15 17:53:03 +00:00
commit 74cfd73b4c
11 changed files with 142 additions and 17 deletions

View File

@ -22,7 +22,8 @@ def add_resources():
DeviceTypeResource,
DeviceTypeListResource,
DeviceConfigurationResource)
from .resources.dashboard import DashboardResource, DashboardListResource
from .resources.dashboard import (DashboardResource,
DashboardListResource)
api.add_resource(AccountResource, '/v1/accounts/<int:account_id>')
api.add_resource(AccountListResource, '/v1/accounts')
@ -44,9 +45,9 @@ def add_resources():
api.add_resource(DeviceTypeListResource, '/v1/devices/types')
api.add_resource(DeviceConfigurationResource,
'/v1/devices/<int:device_id>/configuration')
api.add_resource(DashboardListResource, '/v1/dashboards')
api.add_resource(DashboardResource,
'/v1/dashboards/<int:dashboard_id>')
api.add_resource(DashboardListResource, '/v1/dashboards')
add_resources()

View File

@ -1,6 +1,6 @@
from flask import g
from flask import g, request
from flask_restful import abort
from marshmallow import fields
from marshmallow import fields, Schema
from webargs.flaskparser import use_args
from flasgger import swag_from
import app.dashboards.api as dashboard
@ -10,9 +10,14 @@ from app.api.schemas import BaseResourceSchema
class DashboardSchema(BaseResourceSchema):
id = fields.Integer(dump_only=True)
active = fields.Boolean(required=False)
dashboard_data = fields.Raw()
class DashboardIdSchema(Schema):
id = fields.Integer()
class DashboardResource(ProtectedResource):
@swag_from('swagger/get_dashboard_spec.yaml')
def get(self, dashboard_id):
@ -29,9 +34,30 @@ class DashboardResource(ProtectedResource):
if requested_dashboard.account_id != g.current_account.id:
abort(403, message='You are not allowed to access this dashboard',
status='error')
success = dashboard.update_dashboard(
if args.get('dashboard_data') is None:
abort(400, message='Missing dashboard_data', status='error')
if args.get('active') is None:
abort(400, message='Missing active', status='error')
success = dashboard.patch_dashboard(
g.current_account.id,
dashboard_id,
args['dashboard_data'])
args['dashboard_data'],
args['active'])
if success:
return '', 204
@use_args(DashboardSchema(), locations=('json',))
@swag_from('swagger/update_dashboard_spec.yaml')
def patch(self, args, dashboard_id):
requested_dashboard = dashboard.get_dashboard(dashboard_id)
if requested_dashboard.account_id != g.current_account.id:
abort(403, message='You are not allowed to access this dashboard',
status='error')
success = dashboard.patch_dashboard(
g.current_account.id,
dashboard_id,
args.get('dashboard_data'),
args.get('active'))
if success:
return '', 204
@ -57,5 +83,8 @@ class DashboardListResource(ProtectedResource):
@swag_from('swagger/get_dashboards_spec.yaml')
def get(self):
request_args = request.args
return DashboardSchema().dump(
dashboard.get_dashboards(g.current_account.id), many=True), 200
dashboard.get_dashboards(
g.current_account.id,
request_args.get('active')), many=True), 200

View File

@ -2,6 +2,13 @@ Gets all associated dashboards
---
tags:
- Dashboard
parameters:
- in: query
name: active
required: false
schema:
type: boolean
description: Filter for whether to display only active dashboard
responses:
200:
description: Success

View File

@ -3,14 +3,14 @@ Gets all associated devices
tags:
- Device
parameters:
- in: path
- in: query
name: page
required: false
schema:
type: integer
minimum: 1
description: requested page
- in: path
- in: query
name: per_page
required: false
schema:

View File

@ -1,4 +1,5 @@
Updates a dashboard
Updating active state disables previous active dashboard
---
tags:
- Dashboard

View File

@ -23,7 +23,7 @@ class TokenResource(Resource):
args['password'])
if token:
return {'status': 'success', 'token': token}, 200
except ValueError, e:
except ValueError as e:
abort(401, message=str(e), status='error')

View File

@ -29,7 +29,8 @@ def get_dashboard(dashboard_id):
return Dashboard.get(id=dashboard_id)
def update_dashboard(dashboard_id, dashboard_data):
def patch_dashboard(account_id, dashboard_id,
dashboard_data=None, active=None):
"""
Tries to update dashboard with given parameters
@ -38,9 +39,12 @@ def update_dashboard(dashboard_id, dashboard_data):
:type name: JSON
:type dashboard_id: int
"""
dashboard = Dashboard.get(id=dashboard_id)
dashboard.dashboard_data = dashboard_data
dashboard.save()
if dashboard_data is not None:
dashboard = Dashboard.get(id=dashboard_id)
dashboard.dashboard_data = dashboard_data
dashboard.save()
if active:
set_active_dashboard(account_id, dashboard_id)
def delete_dashboard(dashboard_id):
@ -54,13 +58,42 @@ def delete_dashboard(dashboard_id):
dashboard.delete()
def get_dashboards(account_id):
def set_active_dashboard(account_id, dashboard_id):
"""
Tries to set given dashboard as active
:param dashboard_id: Id of requested dashboard
:type name: int
:param dashboard_id: Id of owner account
:type name: int
"""
Dashboard.deactivate_all_for_user(account_id)
dashboard = Dashboard.get(id=dashboard_id)
dashboard.active = True
dashboard.save()
def get_active_dashboard(account_id):
"""
Tries to fetch active dashboard owned by account with given id
:param account_id: Id of owner account
:type name: int
:returns: active Dashboard object
:rtype: Dashboard
"""
return Dashboard.get(account_id=account_id, active=True)
def get_dashboards(account_id, active):
"""
Tries to fetch dashboards owned by account with given id
:param account_id: Id of owner account
:type name: int
:param active: Whether to filter active only
:type name: bool
:returns: Dashboard list
:rtype: List of Dashboard
"""
return Dashboard.get_many(account_id=account_id)
return Dashboard.get_many_filtered(account_id=account_id, active=active)

View File

@ -9,6 +9,7 @@ class Dashboard(db.Model):
dashboard_data = db.Column(JSON, nullable=False)
account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'),
primary_key=True)
active = db.Column(db.Boolean, nullable=False, default=False)
created_at = db.Column(db.DateTime,
nullable=False,
default=db.func.current_timestamp())
@ -74,6 +75,28 @@ class Dashboard(db.Model):
"""
return Dashboard.query.filter_by(**kwargs).all()
@staticmethod
def get_many_filtered(account_id, active):
"""
Get many dashboard with given filters
Available filters:
* active
"""
query = Dashboard.query.filter(Dashboard.account_id == account_id)
if active is not None:
query = query.filter(Dashboard.active == active)
return query.all()
@staticmethod
def deactivate_all_for_user(account_id):
"""
Deactivates all dashboards for this user
"""
db.session.query(Dashboard).filter(account_id == account_id) \
.update({'active': False})
db.session.commit()
@staticmethod
def get(**kwargs):
"""

View File

@ -224,10 +224,13 @@ definitions:
DashboardCreation:
type: object
required:
- active
- dashboard_data
properties:
dashboard_data:
$ref: '#/definitions/dashboarddata'
active:
type: boolean
UnauthorizedError:
type: object

View File

@ -0,0 +1,29 @@
"""empty message
Revision ID: 4945e4c8fbca
Revises: ae43d7caad52
Create Date: 2018-10-10 22:50:41.087670
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '4945e4c8fbca'
down_revision = 'ae43d7caad52'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('dashboards', sa.Column('active', sa.Boolean(),
nullable=False, server_default='False'))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('dashboards', 'active')
# ### end Alembic commands ###

View File

@ -1 +0,0 @@
python-2.7.15