Skip to content
This repository has been archived by the owner on Mar 24, 2021. It is now read-only.

Commit

Permalink
Enable clone dashboard
Browse files Browse the repository at this point in the history
When the user clicks 'Clone module' on a new or existing dashboard it
will redirect to a page containing a dropdown of dashboards to select
from and the form progress will be saved in the session (because of the
update_modules_form_and_redirect decorator). When the user selects a
dashboard and submits it will redirect back to the page, but now there
will also be a dropdown containing modules on the selected dashboard.
Clicking a link in this dropdown will redirect to the original dashboard
page with the module now appended to the form using the following
mechanism:

A link of the format 'admin/dashboards/new?clone_module={module_id}' or 'admin/dashboards/dashboard_uuid?clone_module={module_id}' which when followed will redirect to a new or the existing dashboard with anything in the session still there and the new module prefilled and present.
  • Loading branch information
jcbashdown committed May 8, 2015
1 parent a6e3991 commit b1dcef7
Show file tree
Hide file tree
Showing 7 changed files with 507 additions and 27 deletions.
4 changes: 4 additions & 0 deletions application/assets/scss/performanceplatform-admin/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,7 @@ ul.checkbox-set {
border-radius: 3px;
color: black;
}

select#dashboard-uuid {
max-width: 600px;
}
84 changes: 77 additions & 7 deletions application/controllers/admin/dashboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
flash, redirect, render_template, request,
session, url_for
)
from application.forms import convert_to_dashboard_form
from application.forms import(
convert_to_dashboard_form,
convert_to_module_for_form)

import cgi
import json
Expand Down Expand Up @@ -50,6 +52,11 @@ def set_section_module_choices(modules):
if uuid is not None:
session['pending_dashboard']['uuid'] = uuid

if 'clone_module' in request.form:
url = url_for('clone_module',
target_dashboard_uuid=uuid)
return redirect(url)

if 'add_section' in request.form:
url = url_for('dashboard_form',
uuid=uuid,
Expand Down Expand Up @@ -89,17 +96,29 @@ def should_use_session(session, uuid):
return True
return False

def append_cloned_module():
if request.args.get('clone_module'):
module = admin_client.get_module(
request.args.get('clone_module'))
module_form = convert_to_module_for_form(
module, module_types, cloned=True)
form.modules.append_entry(module_form)
add_select_options_to_module()

def append_new_module_forms():
total_modules = int(request.args.get('modules'))
modules_required = total_modules - len(form.modules)
for i in range(modules_required):
form.modules.append_entry()
choices = module_types.get_visualisation_choices()
form.modules[-1].module_type.choices = choices
choices = data_sources.group_choices()
form.modules[-1].data_group.choices = choices
choices = data_sources.type_choices()
form.modules[-1].data_type.choices = choices
add_select_options_to_module()

def add_select_options_to_module():
choices = module_types.get_visualisation_choices()
form.modules[-1].module_type.choices = choices
choices = data_sources.group_choices()
form.modules[-1].data_group.choices = choices
choices = data_sources.type_choices()
form.modules[-1].data_type.choices = choices

template_context = base_template_context()
template_context['user'] = session['oauth_user']
Expand Down Expand Up @@ -131,12 +150,63 @@ def append_new_module_forms():
append_new_module_forms()
if request.args.get('section'):
form.modules[-1].category.data = 'container'
if request.args.get('clone_module'):
append_cloned_module()

return render_template('dashboards/create.html',
form=form,
**template_context)


@app.route('{0}/clone_module/<target_dashboard_uuid>'.format(
DASHBOARD_ROUTE), methods=['POST', 'GET'])
@app.route('{0}/clone_module'.format(
DASHBOARD_ROUTE), methods=['POST', 'GET'])
@requires_authentication
@requires_permission('dashboard')
def clone_module(admin_client, target_dashboard_uuid=None):
modules = None
dashboards = None
target_dashboard_url = None
source_dashboard_uuid = None
selected_dashboard = None

dashboards_url = '{0}/dashboards'.format(
app.config['STAGECRAFT_HOST'])
access_token = session['oauth_token']['access_token']
headers = {
'Authorization': 'Bearer {0}'.format(access_token),
}
dashboard_response = requests.get(dashboards_url, headers=headers)
if dashboard_response.status_code == 200:
dashboards = dashboard_response.json()['dashboards']
if request.form and 'dashboard_uuid' in request.form:
source_dashboard_uuid = request.form['dashboard_uuid']
modules = admin_client.list_modules_on_dashboard(
source_dashboard_uuid)
selected_dashboard = next(
dashboard for dashboard in dashboards
if dashboard['id'] == source_dashboard_uuid)

if target_dashboard_uuid:
target_dashboard_url = '/admin/dashboards/{}'.format(
target_dashboard_uuid)
else:
target_dashboard_url = '/admin/dashboards/new'

template_context = base_template_context()
template_context['user'] = session['oauth_user']

return render_template('dashboards/clone_module.html',
modules=modules,
dashboards=dashboards,
target_dashboard_url=target_dashboard_url,
source_dashboard_uuid=source_dashboard_uuid,
selected_dashboard=selected_dashboard,
target_dashboard_uuid=target_dashboard_uuid,
**template_context)


@app.route('{0}/clone'.format(DASHBOARD_ROUTE), methods=['GET'])
@requires_authentication
@requires_permission('dashboard')
Expand Down
54 changes: 35 additions & 19 deletions application/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,45 @@
import json


def convert_to_module_for_form(module, module_types, cloned=False):
module['info'] = json.dumps(module['info'])
if module['query_parameters'] is not None:
module['query_parameters'] = json.dumps(module['query_parameters'])
module['options'] = json.dumps(module['options'])
module['module_type'] = module['type']['id']
if module['module_type'] == module_types.get_section_type()['id']:
module['category'] = 'container'
if cloned:
module['id'] = None
module['uuid'] = module['id']
return module


def flatten_module(module, module_types):
if module['type']['id'] == module_types.get_section_type()['id']:
child_modules = module['modules']
modules = [module]
modules.extend(flatten_modules(child_modules, module_types))
return modules
else:
return [module]


def flatten_modules(modules, module_types):
flattened_modules = []
for module in modules:
flattened_modules.extend(flatten_module(module, module_types))
return flattened_modules


def convert_to_dashboard_form(
dashboard_dict, admin_client, module_types, data_sources):
def flatten_modules(modules):
flattened_modules = []
for module in modules:
if module['type']['id'] == module_types.get_section_type()['id']:
child_modules = module['modules']
flattened_modules.append(module)
flattened_modules.extend(flatten_modules(child_modules))
else:
flattened_modules.append(module)
return flattened_modules

dashboard_dict['modules'] = flatten_modules(dashboard_dict['modules'])
dashboard_dict['modules'] = flatten_modules(
dashboard_dict['modules'],
module_types)
for module in dashboard_dict['modules']:
module['info'] = json.dumps(module['info'])
if module['query_parameters'] is not None:
module['query_parameters'] = json.dumps(module['query_parameters'])
module['options'] = json.dumps(module['options'])
module['module_type'] = module['type']['id']
if module['module_type'] == module_types.get_section_type()['id']:
module['category'] = 'container'
module['uuid'] = module['id']
convert_to_module_for_form(module, module_types)
transaction_link = [link for link
in dashboard_dict['links']
if link['type'] == 'transaction']
Expand Down
53 changes: 53 additions & 0 deletions application/templates/dashboards/clone_module.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

{% extends "base.html" %}

{% block body %}
<div class="row">
<div class="col-lg-12">
{% if dashboards %}
<form method="post" action="{{ url_for('clone_module', target_dashboard_uuid=target_dashboard_uuid) }}" role="form" class="form-inline">
<div class='form-group'>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<label for="dashboard_uuid">Select dashboard: </label>
<select class='form-control' name="dashboard_uuid" id="dashboard-uuid">
{% for dashboard in dashboards %}
{% if(source_dashboard_uuid == dashboard.id) %}
<option selected value="{{dashboard.id}}">
{{ dashboard.title }}
</option>
{% else %}
<option value="{{dashboard.id}}">
{{ dashboard.title }}
</option>
{% endif %}
{% endfor %}
</select>
<input type="submit" class="btn btn-default" value="Get modules" name="modules_for_dashboard">
{% if modules %}
<div class="btn-group">
<button class="btn btn-primary dropdown-toggle" type="button" id="module-select" data-toggle="dropdown" aria-expanded="true">
Select modules from {{selected_dashboard.title}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="module-select">
{% for module in modules %}
<li role="presentation">
<a role="menuitem" tabindex="-1" href="{{'{}?clone_module={}'.format(target_dashboard_url, module.id)}}">{{ module.title }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</form>
{% endif %}
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
{% endblock %}

{% block footer_javascripts %}
<script src='/static/javascripts/jsonlint/jsonlint.js'></script>
<script src='/static/javascripts/sticky-kit/sticky-kit.js'></script>
<script src='/static/javascripts/sortable/jquery.sortable.min.js'></script>
<script src='/static/javascripts/edit_dashboard.js'></script>
{% endblock %}
3 changes: 3 additions & 0 deletions application/templates/dashboards/create.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ <h3><small>Modules</small></h3>
<p>
<input type="submit" class="btn btn-default" value="Add a module" name="add_module">
</p>
<p>
<input type="submit" class="btn btn-default" value="Clone a module" name="clone_module">
</p>
<p>
{% if uuid %}
<input type="submit" class="btn btn-success" value="Update dashboard" name="create">
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ graphviz==0.4.2
gunicorn==18.0
logstash_formatter==0.5.7
ndg-httpsclient==0.3.2
performanceplatform-client==0.8.1
performanceplatform-client==0.9.6
pyasn1==0.1.7
pyOpenSSL==0.14
pytz==2014.4
Expand Down

0 comments on commit b1dcef7

Please sign in to comment.