Add dashboard widgets
parent
a6e85614d2
commit
a0a0e5b085
|
@ -23,7 +23,9 @@ def add_resources():
|
||||||
DeviceTypeListResource,
|
DeviceTypeListResource,
|
||||||
DeviceConfigurationResource)
|
DeviceConfigurationResource)
|
||||||
from .resources.dashboard import (DashboardResource,
|
from .resources.dashboard import (DashboardResource,
|
||||||
DashboardListResource)
|
DashboardListResource,
|
||||||
|
DashboardWidgetResource,
|
||||||
|
DashboardWidgetListResource)
|
||||||
|
|
||||||
api.add_resource(AccountResource, '/v1/accounts/<int:account_id>')
|
api.add_resource(AccountResource, '/v1/accounts/<int:account_id>')
|
||||||
api.add_resource(AccountListResource, '/v1/accounts')
|
api.add_resource(AccountListResource, '/v1/accounts')
|
||||||
|
@ -48,6 +50,11 @@ def add_resources():
|
||||||
api.add_resource(DashboardResource,
|
api.add_resource(DashboardResource,
|
||||||
'/v1/dashboards/<int:dashboard_id>')
|
'/v1/dashboards/<int:dashboard_id>')
|
||||||
api.add_resource(DashboardListResource, '/v1/dashboards')
|
api.add_resource(DashboardListResource, '/v1/dashboards')
|
||||||
|
api.add_resource(
|
||||||
|
DashboardWidgetResource,
|
||||||
|
'/v1/dashboards/<int:dashboard_id>/widgets/<int:widget_id>')
|
||||||
|
api.add_resource(DashboardWidgetListResource,
|
||||||
|
'/v1/dashboards/<int:dashboard_id>/widgets')
|
||||||
|
|
||||||
|
|
||||||
add_resources()
|
add_resources()
|
||||||
|
|
|
@ -4,6 +4,7 @@ from marshmallow import fields
|
||||||
from webargs.flaskparser import use_args
|
from webargs.flaskparser import use_args
|
||||||
from flasgger import swag_from
|
from flasgger import swag_from
|
||||||
import app.dashboards.api as dashboard
|
import app.dashboards.api as dashboard
|
||||||
|
import app.devices.api as device
|
||||||
from app.api.auth_protection import ProtectedResource
|
from app.api.auth_protection import ProtectedResource
|
||||||
from app.api.schemas import BaseResourceSchema
|
from app.api.schemas import BaseResourceSchema
|
||||||
|
|
||||||
|
@ -15,6 +16,17 @@ class DashboardSchema(BaseResourceSchema):
|
||||||
name = fields.String()
|
name = fields.String()
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardWidgetSchema(BaseResourceSchema):
|
||||||
|
id = fields.Integer(dump_only=True)
|
||||||
|
device_id = fields.Integer()
|
||||||
|
height = fields.Integer()
|
||||||
|
width = fields.Integer()
|
||||||
|
x = fields.Integer()
|
||||||
|
y = fields.Integer()
|
||||||
|
chart_type = fields.String()
|
||||||
|
filters = fields.Raw()
|
||||||
|
|
||||||
|
|
||||||
class DashboardResource(ProtectedResource):
|
class DashboardResource(ProtectedResource):
|
||||||
@swag_from('swagger/get_dashboard_spec.yaml')
|
@swag_from('swagger/get_dashboard_spec.yaml')
|
||||||
def get(self, dashboard_id):
|
def get(self, dashboard_id):
|
||||||
|
@ -84,3 +96,108 @@ class DashboardListResource(ProtectedResource):
|
||||||
dashboard.get_dashboards(
|
dashboard.get_dashboards(
|
||||||
g.current_account.id,
|
g.current_account.id,
|
||||||
request_args.get('active')), many=True), 200
|
request_args.get('active')), many=True), 200
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardWidgetListResource(ProtectedResource):
|
||||||
|
@use_args(DashboardWidgetSchema(), locations=('json',))
|
||||||
|
@swag_from('swagger/create_dashboard_widget_spec.yaml')
|
||||||
|
def post(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')
|
||||||
|
if not device.can_user_access_device(g.current_account.id,
|
||||||
|
args['device_id']):
|
||||||
|
abort(403, message='You are not allowed to access this device',
|
||||||
|
status='error')
|
||||||
|
success = dashboard.create_widget(
|
||||||
|
dashboard_id,
|
||||||
|
args['device_id'],
|
||||||
|
args['height'],
|
||||||
|
args['width'],
|
||||||
|
args['x'],
|
||||||
|
args['y'],
|
||||||
|
args['chart_type'],
|
||||||
|
args['filters'])
|
||||||
|
if success:
|
||||||
|
return '', 201
|
||||||
|
|
||||||
|
@swag_from('swagger/get_dashboard_widgets_spec.yaml')
|
||||||
|
def get(self, 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')
|
||||||
|
return DashboardWidgetSchema().dump(
|
||||||
|
dashboard.get_widgets(dashboard_id), many=True), 200
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardWidgetResource(ProtectedResource):
|
||||||
|
@swag_from('swagger/get_dashboard_widget_spec.yaml')
|
||||||
|
def get(self, dashboard_id, widget_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 widget',
|
||||||
|
status='error')
|
||||||
|
requested_widget = dashboard.get_widget(widget_id)
|
||||||
|
return DashboardWidgetSchema().dump(requested_widget), 200
|
||||||
|
|
||||||
|
@use_args(DashboardWidgetSchema(), locations=('json',))
|
||||||
|
@swag_from('swagger/update_dashboard_widget_spec.yaml')
|
||||||
|
def put(self, args, dashboard_id, widget_id):
|
||||||
|
print("Received stuff!")
|
||||||
|
print("Args: " + str(args))
|
||||||
|
print("Dashboard_id: " + str(dashboard_id))
|
||||||
|
print("Widget_id: " + str(widget_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')
|
||||||
|
if not device.can_user_access_device(g.current_account.id,
|
||||||
|
args['device_id']):
|
||||||
|
abort(403, message='You are not allowed to access this device',
|
||||||
|
status='error')
|
||||||
|
success = dashboard.patch_widget(
|
||||||
|
widget_id,
|
||||||
|
args['device_id'],
|
||||||
|
args['height'],
|
||||||
|
args['width'],
|
||||||
|
args['x'],
|
||||||
|
args['y'],
|
||||||
|
args['chart_type'],
|
||||||
|
args['filters'])
|
||||||
|
if success:
|
||||||
|
return '', 204
|
||||||
|
|
||||||
|
@use_args(DashboardWidgetSchema(partial=True), locations=('json',))
|
||||||
|
@swag_from('swagger/update_dashboard_widget_spec.yaml')
|
||||||
|
def patch(self, args, dashboard_id, widget_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')
|
||||||
|
if args.get('device_id') is not None:
|
||||||
|
if not device.can_user_access_device(g.current_account.id,
|
||||||
|
args['device_id']):
|
||||||
|
abort(403, message='You are not allowed to access this device',
|
||||||
|
status='error')
|
||||||
|
success = dashboard.patch_widget(
|
||||||
|
widget_id,
|
||||||
|
args.get('device_id'),
|
||||||
|
args.get('height'),
|
||||||
|
args.get('width'),
|
||||||
|
args.get('x'),
|
||||||
|
args.get('y'),
|
||||||
|
args.get('chart_type'),
|
||||||
|
args.get('filters'))
|
||||||
|
if success:
|
||||||
|
return '', 204
|
||||||
|
|
||||||
|
@swag_from('swagger/delete_dashboard_widget_spec.yaml')
|
||||||
|
def delete(self, dashboard_id, widget_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')
|
||||||
|
dashboard.delete_widget(widget_id)
|
||||||
|
return '', 204
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
Creates new dashboard widget
|
||||||
|
Requires Widget object and creates dashboard
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Dashboard
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: dashboard_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the owning dashboard
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: '#/definitions/WidgetCreation'
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: Successful creation
|
|
@ -1,4 +1,4 @@
|
||||||
Deletes a dashboard
|
Deletes a widget
|
||||||
---
|
---
|
||||||
tags:
|
tags:
|
||||||
- Dashboard
|
- Dashboard
|
||||||
|
@ -8,6 +8,11 @@ parameters:
|
||||||
required: true
|
required: true
|
||||||
type: integer
|
type: integer
|
||||||
description: Id of the dashboard
|
description: Id of the dashboard
|
||||||
|
- in: path
|
||||||
|
name: widget_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the widget
|
||||||
responses:
|
responses:
|
||||||
204:
|
204:
|
||||||
description: Success
|
description: Success
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
Deletes a dashboard
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Dashboard
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: dashboard_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the dashboard
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: Success
|
|
@ -0,0 +1,26 @@
|
||||||
|
Gets a widget
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Dashboard
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: dashboard_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the dashboard
|
||||||
|
- in: path
|
||||||
|
name: widget_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the widget
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- content
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
$ref: '#/definitions/Widget'
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
Gets all widgets of a dashboard
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Dashboard
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: dashboard_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the dashboard
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Success
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- content
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/Widget'
|
|
@ -14,11 +14,7 @@ parameters:
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
required:
|
$ref: '#/definitions/DashboardCreation'
|
||||||
- dashboard
|
|
||||||
properties:
|
|
||||||
device:
|
|
||||||
$ref: '#/definitions/DashboardCreation'
|
|
||||||
responses:
|
responses:
|
||||||
204:
|
204:
|
||||||
description: Success
|
description: Success
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
Updates a widget
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- Dashboard
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: dashboard_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the dashboard
|
||||||
|
- in: path
|
||||||
|
name: widget_id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
description: Id of the widget
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: '#/definitions/WidgetCreation'
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: Success
|
|
@ -1,4 +1,4 @@
|
||||||
from .models import Dashboard
|
from .models import Dashboard, DashboardWidget
|
||||||
|
|
||||||
|
|
||||||
# Public interface
|
# Public interface
|
||||||
|
@ -101,3 +101,80 @@ def get_dashboards(account_id, active):
|
||||||
:rtype: List of Dashboard
|
:rtype: List of Dashboard
|
||||||
"""
|
"""
|
||||||
return Dashboard.get_many_filtered(account_id=account_id, active=active)
|
return Dashboard.get_many_filtered(account_id=account_id, active=active)
|
||||||
|
|
||||||
|
|
||||||
|
def create_widget(dashboard_id, device_id, height, width, x, y,
|
||||||
|
chart_type, filters):
|
||||||
|
"""
|
||||||
|
Tries to create a dashboard widget
|
||||||
|
"""
|
||||||
|
widget = DashboardWidget(dashboard_id, device_id, height, width, x, y,
|
||||||
|
chart_type, filters)
|
||||||
|
widget.save()
|
||||||
|
|
||||||
|
|
||||||
|
def delete_widget(widget_id):
|
||||||
|
"""
|
||||||
|
Tries to delete widget with given id
|
||||||
|
|
||||||
|
:param widget_id: Id of requested widget
|
||||||
|
:type name: int
|
||||||
|
"""
|
||||||
|
widget = DashboardWidget.get(id=widget_id)
|
||||||
|
widget.delete()
|
||||||
|
|
||||||
|
|
||||||
|
def get_widgets(dashboard_id):
|
||||||
|
"""
|
||||||
|
Tries to fetch widgets of a dashboard with dashboard_id
|
||||||
|
|
||||||
|
:param dashboard_id: Id of owner dashboard
|
||||||
|
:type name: int
|
||||||
|
:returns: Widget list
|
||||||
|
:rtype: List of Widgets
|
||||||
|
"""
|
||||||
|
return DashboardWidget.get_many_for_dashboard(dashboard_id)
|
||||||
|
|
||||||
|
|
||||||
|
def get_widget(widget_id):
|
||||||
|
"""
|
||||||
|
Tries to fetch widget with given id
|
||||||
|
|
||||||
|
:param widget_id: Id of requested dashboard
|
||||||
|
:type name: int
|
||||||
|
:returns: Widget object
|
||||||
|
:rtype: Widget
|
||||||
|
"""
|
||||||
|
return DashboardWidget.get(id=widget_id)
|
||||||
|
|
||||||
|
|
||||||
|
def patch_widget(widget_id, device_id=None, height=None, width=None,
|
||||||
|
x=None, y=None, chart_type=None, filters=None):
|
||||||
|
"""
|
||||||
|
Tries to update widget with given parameters
|
||||||
|
"""
|
||||||
|
widget = DashboardWidget.get(id=widget_id)
|
||||||
|
|
||||||
|
if device_id is not None:
|
||||||
|
widget.device_id = device_id
|
||||||
|
|
||||||
|
if height is not None:
|
||||||
|
widget.height = height
|
||||||
|
|
||||||
|
if width is not None:
|
||||||
|
widget.width = width
|
||||||
|
|
||||||
|
if x is not None:
|
||||||
|
widget.x = x
|
||||||
|
|
||||||
|
if y is not None:
|
||||||
|
widget.y = y
|
||||||
|
|
||||||
|
if chart_type is not None:
|
||||||
|
widget.chart_type = chart_type
|
||||||
|
|
||||||
|
if filters is not None:
|
||||||
|
widget.filters = filters
|
||||||
|
|
||||||
|
widget.save()
|
||||||
|
print("Saved widget")
|
||||||
|
|
|
@ -113,3 +113,121 @@ class Dashboard(db.Model):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Dashboard (dashboard_data=%s, account_id=%s)>' % (
|
return '<Dashboard (dashboard_data=%s, account_id=%s)>' % (
|
||||||
self.dashboard_data, self.account_id)
|
self.dashboard_data, self.account_id)
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardWidget(db.Model):
|
||||||
|
__tablename__ = 'dashboard_widgets'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
dashboard_id = db.Column(db.Integer, db.ForeignKey('dashboards.id'))
|
||||||
|
device_id = db.Column(db.Integer, db.ForeignKey('devices.id'))
|
||||||
|
height = db.Column(db.Integer, nullable=False)
|
||||||
|
width = db.Column(db.Integer, nullable=False)
|
||||||
|
x = db.Column(db.Integer, nullable=False)
|
||||||
|
y = db.Column(db.Integer, nullable=False)
|
||||||
|
chart_type = db.Column(db.String, nullable=False)
|
||||||
|
filters = db.Column(JSON, nullable=False)
|
||||||
|
created_at = db.Column(db.DateTime,
|
||||||
|
nullable=False,
|
||||||
|
default=db.func.current_timestamp())
|
||||||
|
modified_at = db.Column(db.DateTime,
|
||||||
|
nullable=False,
|
||||||
|
default=db.func.current_timestamp(),
|
||||||
|
onupdate=db.func.current_timestamp())
|
||||||
|
|
||||||
|
def __init__(self, dashboard_id, device_id, height, width, x, y,
|
||||||
|
chart_type, filters):
|
||||||
|
self.dashboard_id = dashboard_id
|
||||||
|
self.device_id = device_id
|
||||||
|
self.height = height
|
||||||
|
self.width = width
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.chart_type = chart_type
|
||||||
|
self.filters = filters
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
"""
|
||||||
|
Stores this widget to database
|
||||||
|
This may raise errors
|
||||||
|
"""
|
||||||
|
db.session.add(self)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
"""
|
||||||
|
Deletes this widget from database
|
||||||
|
"""
|
||||||
|
db.session.delete(self)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists_with_any_of(**kwargs):
|
||||||
|
"""
|
||||||
|
Checks if widget with any of the given arguments exists
|
||||||
|
"""
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
args = {key: value}
|
||||||
|
if DashboardWidget.query.filter_by(**args).first():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def exists(**kwargs):
|
||||||
|
"""
|
||||||
|
Checks if widget with all of the given arguments exists
|
||||||
|
"""
|
||||||
|
if DashboardWidget.query.filter_by(**kwargs).first():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_all():
|
||||||
|
"""
|
||||||
|
Get all stored widgets
|
||||||
|
"""
|
||||||
|
return DashboardWidget.query.paginate(None, None, False).items
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_many(**kwargs):
|
||||||
|
"""
|
||||||
|
Get widgets with given filters
|
||||||
|
|
||||||
|
Available filters:
|
||||||
|
* id
|
||||||
|
* dashboard_id
|
||||||
|
* device_id
|
||||||
|
* dimensions and positions, but useless
|
||||||
|
* chart_type
|
||||||
|
* filters, but useless
|
||||||
|
"""
|
||||||
|
return DashboardWidget.query.filter_by(**kwargs).paginate(
|
||||||
|
None, None, False).items
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_many_for_dashboard(dashboard_id):
|
||||||
|
"""
|
||||||
|
Get widgets for given dashboard
|
||||||
|
"""
|
||||||
|
query = DashboardWidget.query.filter(
|
||||||
|
DashboardWidget.dashboard_id == dashboard_id)
|
||||||
|
return query.paginate(None, None, False).items
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get(**kwargs):
|
||||||
|
"""
|
||||||
|
Get widget with given filters
|
||||||
|
|
||||||
|
Available filters:
|
||||||
|
* id
|
||||||
|
* dashboard_id
|
||||||
|
* device_id
|
||||||
|
* dimensions and positions, but useless
|
||||||
|
* chart_type
|
||||||
|
* filters, but useless
|
||||||
|
"""
|
||||||
|
return DashboardWidget.query.filter_by(**kwargs).first_or_404()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<DashboardWidget (id=%s, dashboard_id=%s)>' % (
|
||||||
|
self.dashboard_data, self.account_id)
|
||||||
|
|
|
@ -84,6 +84,16 @@ definitions:
|
||||||
description: Dashboard data
|
description: Dashboard data
|
||||||
example: {}
|
example: {}
|
||||||
|
|
||||||
|
filters:
|
||||||
|
type: object
|
||||||
|
description: Dashboard data
|
||||||
|
example: {}
|
||||||
|
|
||||||
|
charttype:
|
||||||
|
type: string
|
||||||
|
description: Type of chart
|
||||||
|
example: line
|
||||||
|
|
||||||
Credentials:
|
Credentials:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
@ -222,6 +232,10 @@ definitions:
|
||||||
$ref: '#/definitions/id'
|
$ref: '#/definitions/id'
|
||||||
dashboard_data:
|
dashboard_data:
|
||||||
$ref: '#/definitions/dashboarddata'
|
$ref: '#/definitions/dashboarddata'
|
||||||
|
active:
|
||||||
|
type: boolean
|
||||||
|
name:
|
||||||
|
type: '#definitions/devicename'
|
||||||
|
|
||||||
DashboardCreation:
|
DashboardCreation:
|
||||||
type: object
|
type: object
|
||||||
|
@ -234,6 +248,66 @@ definitions:
|
||||||
$ref: '#/definitions/dashboarddata'
|
$ref: '#/definitions/dashboarddata'
|
||||||
active:
|
active:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
name:
|
||||||
|
ref: '#definitions/genericname'
|
||||||
|
|
||||||
|
Widget:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- dashboard_id
|
||||||
|
- device_id
|
||||||
|
- width
|
||||||
|
- height
|
||||||
|
- x
|
||||||
|
- y
|
||||||
|
- chart_type
|
||||||
|
- filters
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
dashboard_id:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
device_id:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
width:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
height:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
x:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
y:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
chart_type:
|
||||||
|
$ref: '#/definitions/charttype'
|
||||||
|
filters:
|
||||||
|
$ref: '#/definitions/filters'
|
||||||
|
|
||||||
|
WidgetCreation:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- device_id
|
||||||
|
- width
|
||||||
|
- height
|
||||||
|
- x
|
||||||
|
- y
|
||||||
|
- chart_type
|
||||||
|
- filters
|
||||||
|
properties:
|
||||||
|
device_id:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
width:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
height:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
x:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
y:
|
||||||
|
$ref: '#/definitions/id'
|
||||||
|
chart_type:
|
||||||
|
$ref: '#/definitions/charttype'
|
||||||
|
filters:
|
||||||
|
$ref: '#/definitions/filters'
|
||||||
|
|
||||||
UnauthorizedError:
|
UnauthorizedError:
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: b5eb4a04c77e
|
||||||
|
Revises: 5cce35244087
|
||||||
|
Create Date: 2018-10-22 23:11:50.584996
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'b5eb4a04c77e'
|
||||||
|
down_revision = '5cce35244087'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.create_table('dashboard_widgets',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('dashboard_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('device_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('height', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('width', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('x', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('y', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('chart_type', sa.String(), nullable=False),
|
||||||
|
sa.Column('filters', postgresql.JSON(astext_type=sa.Text()), nullable=False),
|
||||||
|
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||||
|
sa.Column('modified_at', sa.DateTime(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['dashboard_id'], ['dashboards.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['device_id'], ['devices.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_table('dashboard_widgets')
|
||||||
|
# ### end Alembic commands ###
|
Loading…
Reference in New Issue