def move_tile(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] target_dashboard_id = request.get_json()['target_dashboard_id'] for_layout_id = request.get_json()['for_layout_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) check_access(lambda: auth.access_dashboard(target_dashboard_id)) old_tile = tiles.Tile.select(dashboard_id, tile_id) if not old_tile: return error('Invalid source tile in move_tile %s %s' % (dashboard_id, tile_id)) new_tile = old_tile.copy(target_dashboard_id) if not layouts.place_tile(new_tile): return error('Cannot copy the source file') mres = layouts.detach_tile(old_tile, for_layout_id=for_layout_id) if not mres: return error(message='Deletion of the source tile unsuccessful due to old page data') log.info('Moved tile tile_id=%s dashboard_id=%s to tile tile_id=%s dashboard_id=%s', tile_id, dashboard_id, new_tile.tile_id, target_dashboard_id) return success(result=dict(new_layout_id=mres.new_layout.layout_id))
def replace_tile(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] report_id = request.get_json()['report_id'] tile_config = request.get_json()['tile_config'] for_layout_id = request.get_json()['for_layout_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) check_access(lambda: auth.access_report_instances(report_id)) tile = tiles.Tile.select(dashboard_id, tile_id) if not tile: return error(message='No tile found, please refresh the page') new_tile = tile.insert_similar(tile_config) repl_res = layouts.replace_tiles({tile: new_tile}, for_layout_id) if not repl_res: return error('A newer version of the dashboard is available, please refresh the page') log.info('Replaced tile %s with tile %s', tile_id, new_tile.tile_id) dataseries.update_default_options(new_tile) tpcreated_replacement = [[t1.tile_id, t2.tile_id] for (t1, t2) in repl_res.tile_replacement.items() if t2 != new_tile] return success(result=dict(new_tile=new_tile, new_layout_id=repl_res.new_layout.layout_id, tpcreated_replacement=tpcreated_replacement))
def create_tile(): dashboard_id = request.get_json()['dashboard_id'] report_id = request.get_json().get('report_id') report_instance_id = request.get_json().get('report_instance_id') tile_config = request.get_json()['tile_config'] moveresize = request.get_json()['moveresize'] for_layout_id = request.get_json()['for_layout_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) check_access(lambda: auth.access_report_instances(report_id)) if tile_config['tags']: tile_config['tile_options']['tpcreator_uispec'] = tpcreator.suggested_tpcreator_uispec( tile_config['tags']) tile = tiles.Tile.insert(auth.logged_owner_id(), report_id, dashboard_id, tile_config) mres = layouts.place_tile(tile, for_layout_id=for_layout_id) if not mres: return error(message='Could not place the new tile on the dashboard, a page refresh is needed') dataseries.update_default_options(tile) log.info('Created new tile report_id=%s dashboard_id=%s tile_id=%s', report_id, dashboard_id, tile.tile_id) tile_html = get_template_attribute('m.html', 'dashboard_tile')\ (tile.tile_id, mres.new_tiles[tile], moveresize) return success(result=dict( tile_html=tile_html, new_layout_id=mres.new_layout.layout_id, ))
def delete_dashboard(): dashboard_id = request.get_json()['dashboard_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) dashboard = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not dashboard: return error('No such dashboard') dashboard.delete() return success()
def fetch_tile_settings(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) tile = tiles.Tile.select(dashboard_id, tile_id) if not tile: return error(message='No tile found, please refresh the page') check_access(lambda: auth.access_report_instances(tile.report_id)) res = {} res['report_id'] = tile.report_id latest_instance_id = tile.report.fetch_latest_instance_id(tile.tile_options['tags']) if not latest_instance_id: return error(message='No report instances for report %s - at least one report instance is needed to display tile settings.' % tile.report.report_name) ri = tile.report.fetch_single_instance(latest_instance_id, tile.tile_options['tags']) res['latest_instance_id'] = latest_instance_id res['html_newest_table'] = get_template_attribute('m.html', 'table_as_html_table')(ri.table) if tile.tile_options['tags']: res['html_selected_tags'] = get_template_attribute('m.html', 'selected_tags')(tile.tile_options['tags']) tpcreator_uispec = tile.tile_options.get('tpcreator_uispec') if not tpcreator_uispec: tpcreator_uispec = tpcreator.suggested_tpcreator_uispec(tile.tile_options['tags']) res['html_tpcreator_content'] = get_template_attribute('m.html', 'tpcreator_content')(tpcreator_uispec) else: res['html_selected_tags'] = None res['html_tpcreator_content'] = None res['tile_options'] = tile.tile_options res['report_name'] = tile.report.report_name html_series_specs = [] for series_spec in tile.series_specs(): data_d = {} cell = series_spec.get_cell(ri) if cell: data_d['sampled-from'] = {'rowno': cell.rowno, 'colno': cell.colno} html_series_specs.append(get_template_attribute('m.html', 'series_spec')(series_spec, ri, data_d)) res['html_all_series_specs'] = '\n'.join(html_series_specs) if tile.tile_options.get('sscs'): res['html_sscs'] = get_template_attribute('m.html', 'series_spec_creator_spec')(tile.tile_options['sscs'], ri) else: res['html_sscs'] = None return success(result=res)
def render_dashboard(): dashboard_id = request.get_json()['dashboard_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) db = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not db: return error('Invalid dashboard') layout = Layout.select(auth.logged_owner_id(), dashboard_id) html = get_template_attribute('m.html', 'dashboard')(db, layout.layout_id if layout else None, layout.layout_dict if layout else None) return success(result=dict(html=html))
def delete_tile(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] for_layout_id = request.get_json()['for_layout_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) tile = tiles.Tile.select(dashboard_id, tile_id) if not tile: return error('Invalid tile') mres = layouts.detach_tile(tile, for_layout_id=for_layout_id) if not mres: return error(message='Could not delete the tile, a page refresh is needed') log.info('Deleted tile dashboard_id=%s tile_id=%s', dashboard_id, tile_id) return success(result=dict(new_layout_id=mres.new_layout.layout_id))
def fetch_move_tile_data(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) dbs = dashboards.OwnerDashboards(auth.logged_owner_id()) options = [(serialize.mjson(db.dashboard_id), db.dashboard_name) for db in dbs.dashboards if db.dashboard_id != dashboard_id] tile = tiles.Tile.select(dashboard_id, tile_id) if not tile: return error('Invalid tile') result = dict( report_name=tile.report.report_name, has_options=bool(options), html_dashboard_select=get_template_attribute('m.html', 'select')('move-to-dashboard-select', options), ) return success(result=result)
def request_expire_tiles_without_data(): dashboard_id = request.get_json()['dashboard_id'] tile_id_list = request.get_json()['tile_id_list'] check_access(lambda: auth.access_dashboard(dashboard_id)) dashboard = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not dashboard: return error('No dashboard') max_seconds_without_data = nestedget(dashboard.dashboard_options, 'max_without_data', 'seconds_back') if not max_seconds_without_data: log.warn('request_expire_tiles_without_data called with empty max_seconds_without_data') return tile_list = tiles.Tile.select_multi(dashboard_id, tile_id_list).values() new_layout_id = tiles.expire_tiles_without_data(tile_list, max_seconds_without_data, None) return success(result=dict(tiles_expired=bool(new_layout_id)))
def set_layout(): dashboard_id = request.get_json()['dashboard_id'] layout_id = request.get_json()['layout_id'] data = request.get_json()['data'] master_tile_id_resized = request.get_json().get('master_tile_id_resized') check_access(lambda: auth.access_dashboard(dashboard_id)) new_layout = Layout(dict(data)) new_layout_id = new_layout.set(auth.logged_owner_id(), dashboard_id, layout_id) reload_required = False if new_layout_id and master_tile_id_resized: master_tile = tiles.Tile.select(dashboard_id, master_tile_id_resized) if master_tile: synced_layout_id = tpcreator.synchronize_sizes_of_tpcreated(master_tile, new_layout_id) reload_required = bool(synced_layout_id) return success(result=dict(new_layout_id=new_layout_id, reload_required=reload_required))
def update_dashboard(): dashboard_id = request.get_json()['dashboard_id'] new_dashboard_name = request.get_json()['new_dashboard_name'].strip() max_without_data = request.get_json().get('max_without_data') enable_synchronizing_tpcreated = request.get_json()['enable_synchronizing_tpcreated'] enable_synchronizing_tpcreated_x_axes = request.get_json()['enable_synchronizing_tpcreated_x_axes'] check_access(lambda: auth.access_dashboard(dashboard_id)) dashboard = dashboards.Dashboard.select(auth.logged_owner_id(), dashboard_id) if not dashboard: return error('Invalid dashboard') res = {} if dashboard.dashboard_name != new_dashboard_name: dashboard.update(dashboard_name=new_dashboard_name) res['new_dashboard_name'] = new_dashboard_name res['reloading_dashboard_required'] = \ dashboard.dashboard_options.get('enable_synchronizing_tpcreated', True) != \ enable_synchronizing_tpcreated or \ dashboard.dashboard_options.get('enable_synchronizing_tpcreated_x_axes', False) != \ enable_synchronizing_tpcreated_x_axes new_dashboard_options = copy.deepcopy(dashboard.dashboard_options) new_dashboard_options['max_without_data'] = max_without_data new_dashboard_options['enable_synchronizing_tpcreated'] = enable_synchronizing_tpcreated new_dashboard_options['enable_synchronizing_tpcreated_x_axes'] = \ enable_synchronizing_tpcreated_x_axes dashboard.update(dashboard_options=new_dashboard_options) res['new_dashboard_options'] = new_dashboard_options log.info('Updated dashboard %s with options %s', dashboard_id, new_dashboard_options) return success(result=res)
def fetch_tile_data(): dashboard_id = request.get_json()['dashboard_id'] tile_id = request.get_json()['tile_id'] check_access(lambda: auth.access_dashboard(dashboard_id)) tile = tiles.Tile.select(dashboard_id, tile_id) if not tile: return error(message='No tile found, please refresh the page', result='NO_TILE_FOUND') check_access(lambda: auth.access_report_instances(tile.report_id)) data = tile.get_tile_data() # Postprocess tile data - generate html if tile.tile_options['drawer_type'] == 'TextTableDrawer': data['drawer_html'] = get_template_attribute('m.html', 'tile_data_as_table')( data, data['series_data_as_rows']) del data['series_data_as_rows'] elif tile.tile_options['drawer_type'] == 'TextSingleDrawer': all_empty = not any(bool(d['data_points']) for d in data['series_data']) data['drawer_html'] = get_template_attribute('m.html', 'tile_data_as_single_text')(data, all_empty) return success(result=dict(tile_options=tile.tile_options, data=data))