def testComputeUnshownColumns_NotAllDefaults(self): shown_cols = ['a', 'b'] config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) config.default_col_spec = self.default_cols config.well_known_labels = [] unshown = table_view_helpers.ComputeUnshownColumns( EMPTY_SEARCH_RESULTS, shown_cols, config, self.builtin_cols) self.assertEquals(unshown, ['c', 'x', 'y', 'z']) unshown = table_view_helpers.ComputeUnshownColumns( SEARCH_RESULTS_WITH_LABELS, shown_cols, config, self.builtin_cols) self.assertEquals( unshown, ['Mstone', 'Priority', 'Visibility', 'c', 'x', 'y', 'z'])
def GetTableViewData( self, mr, results, config, users_by_id, starred_iid_set, related_issues, viewable_iids_set): """EZT template values to render a Table View of issues. Args: mr: commonly used info parsed from the request. results: list of Issue PBs for the search results to be displayed. config: The ProjectIssueConfig PB for the current project. users_by_id: A dictionary {user_id: UserView} for all the users involved in results. starred_iid_set: Set of issues that the user has starred. related_issues: dict {issue_id: issue} of pre-fetched related issues. viewable_iids_set: set of issue ids that are viewable by the user. Returns: Dictionary of page data for rendering of the Table View. """ # We need ordered_columns because EZT loops have no loop-counter available. # And, we use column number in the Javascript to hide/show columns. columns = mr.col_spec.split() ordered_columns = [template_helpers.EZTItem(col_index=i, name=col) for i, col in enumerate(columns)] unshown_columns = table_view_helpers.ComputeUnshownColumns( results, columns, config, tracker_constants.OTHER_BUILT_IN_COLS) lower_columns = mr.col_spec.lower().split() lower_group_by = mr.group_by_spec.lower().split() table_data = _MakeTableData( results, starred_iid_set, lower_columns, lower_group_by, users_by_id, self.GetCellFactories(), related_issues, viewable_iids_set, config) # Used to offer easy filtering of each unique value in each column. column_values = table_view_helpers.ExtractUniqueValues( lower_columns, results, users_by_id, config, related_issues) table_view_data = { 'table_data': table_data, 'column_values': column_values, # Put ordered_columns inside a list of exactly 1 panel so that # it can work the same as the dashboard initial panel list headers. 'panels': [template_helpers.EZTItem(ordered_columns=ordered_columns)], 'unshown_columns': unshown_columns, 'cursor': mr.cursor or mr.preview, 'preview': mr.preview, 'default_colspec': tracker_constants.DEFAULT_COL_SPEC, 'default_results_per_page': tracker_constants.DEFAULT_RESULTS_PER_PAGE, 'csv_link': framework_helpers.FormatURL( [(name, mr.GetParam(name)) for name in framework_helpers.RECOGNIZED_PARAMS], 'csv', num=settings.max_artifact_search_results_per_page), 'preview_on_hover': ezt.boolean( _ShouldPreviewOnHover(mr.auth.user_pb)), } return table_view_data
def GetGridViewData(mr, results, config, users_by_id, starred_iid_set, grid_limited, related_issues, hotlist_context_dict=None): """EZT template values to render a Grid View of issues. Args: mr: commonly used info parsed from the request. results: The Issue PBs that are the search results to be displayed. config: The ProjectConfig PB for the project this view is in. users_by_id: A dictionary {user_id: user_view,...} for all the users involved in results. starred_iid_set: Set of issues that the user has starred. grid_limited: True if the results were limited to fit within the grid. related_issues: dict {issue_id: issue} of pre-fetched related issues. hotlist_context_dict: dict for building a hotlist grid table Returns: Dictionary for EZT template rendering of the Grid View. """ # We need ordered_columns because EZT loops have no loop-counter available. # And, we use column number in the Javascript to hide/show columns. columns = mr.col_spec.split() ordered_columns = [ template_helpers.EZTItem(col_index=i, name=col) for i, col in enumerate(columns) ] other_built_in_cols = (features_constants.OTHER_BUILT_IN_COLS if hotlist_context_dict else tracker_constants.OTHER_BUILT_IN_COLS) unshown_columns = table_view_helpers.ComputeUnshownColumns( results, columns, config, other_built_in_cols) grid_x_attr = (mr.x or config.default_x_attr or '--').lower() grid_y_attr = (mr.y or config.default_y_attr or '--').lower() all_label_values = {} for art in results: all_label_values[art.local_id] = (MakeLabelValuesDict(art)) if grid_x_attr == '--': grid_x_headings = ['All'] else: grid_x_items = table_view_helpers.ExtractUniqueValues( [grid_x_attr], results, users_by_id, config, related_issues, hotlist_context_dict=hotlist_context_dict) grid_x_headings = grid_x_items[0].filter_values if AnyArtifactHasNoAttr(results, grid_x_attr, users_by_id, all_label_values, config, related_issues, hotlist_context_dict=hotlist_context_dict): grid_x_headings.append(framework_constants.NO_VALUES) grid_x_headings = SortGridHeadings(grid_x_attr, grid_x_headings, users_by_id, config, tracker_helpers.SORTABLE_FIELDS) if grid_y_attr == '--': grid_y_headings = ['All'] else: grid_y_items = table_view_helpers.ExtractUniqueValues( [grid_y_attr], results, users_by_id, config, related_issues, hotlist_context_dict=hotlist_context_dict) grid_y_headings = grid_y_items[0].filter_values if AnyArtifactHasNoAttr(results, grid_y_attr, users_by_id, all_label_values, config, related_issues, hotlist_context_dict=hotlist_context_dict): grid_y_headings.append(framework_constants.NO_VALUES) grid_y_headings = SortGridHeadings(grid_y_attr, grid_y_headings, users_by_id, config, tracker_helpers.SORTABLE_FIELDS) logging.info('grid_x_headings = %s', grid_x_headings) logging.info('grid_y_headings = %s', grid_y_headings) grid_data = PrepareForMakeGridData( results, starred_iid_set, grid_x_attr, grid_x_headings, grid_y_attr, grid_y_headings, users_by_id, all_label_values, config, related_issues, hotlist_context_dict=hotlist_context_dict) grid_axis_choice_dict = {} for oc in ordered_columns: grid_axis_choice_dict[oc.name] = True for uc in unshown_columns: grid_axis_choice_dict[uc] = True for bad_axis in tracker_constants.NOT_USED_IN_GRID_AXES: if bad_axis in grid_axis_choice_dict: del grid_axis_choice_dict[bad_axis] grid_axis_choices = grid_axis_choice_dict.keys() grid_axis_choices.sort() grid_cell_mode = mr.cells if len(results) > settings.max_tiles_in_grid and mr.cells == 'tiles': grid_cell_mode = 'ids' grid_view_data = { 'grid_limited': ezt.boolean(grid_limited), 'grid_shown': len(results), 'grid_x_headings': grid_x_headings, 'grid_y_headings': grid_y_headings, 'grid_data': grid_data, 'grid_axis_choices': grid_axis_choices, 'grid_cell_mode': grid_cell_mode, 'results': results, # Really only useful in if-any. } return grid_view_data
def CreateHotlistTableData(mr, hotlist_issues, profiler, services): """Creates the table data for the hotlistissues table.""" with profiler.Phase('getting stars'): starred_iid_set = set( services.issue_star.LookupStarredItemIDs(mr.cnxn, mr.auth.user_id)) with profiler.Phase('Computing col_spec'): mr.ComputeColSpec(mr.hotlist) issues_list = services.issue.GetIssues( mr.cnxn, [hotlist_issue.issue_id for hotlist_issue in hotlist_issues]) with profiler.Phase('Getting config'): hotlist_issues_project_ids = GetAllProjectsOfIssues( [issue for issue in issues_list]) is_cross_project = len(hotlist_issues_project_ids) > 1 config_list = GetAllConfigsOfProjects(mr.cnxn, hotlist_issues_project_ids, services) harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list) (sorted_issues, hotlist_issues_context, issues_users_by_id) = GetSortedHotlistIssues(mr, hotlist_issues, issues_list, harmonized_config, profiler, services) with profiler.Phase("getting related issues"): related_iids = set() results_needing_related = sorted_issues lower_cols = mr.col_spec.lower().split() for issue in results_needing_related: if 'blockedon' in lower_cols: related_iids.update(issue.blocked_on_iids) if 'blocking' in lower_cols: related_iids.update(issue.blocking_iids) if 'mergedinto' in lower_cols: related_iids.add(issue.merged_into) related_issues_list = services.issue.GetIssues(mr.cnxn, list(related_iids)) related_issues = { issue.issue_id: issue for issue in related_issues_list } with profiler.Phase('building table'): context_for_all_issues = { issue.issue_id: hotlist_issues_context[issue.issue_id] for issue in sorted_issues } column_values = table_view_helpers.ExtractUniqueValues( mr.col_spec.lower().split(), sorted_issues, issues_users_by_id, harmonized_config, related_issues, hotlist_context_dict=context_for_all_issues) unshown_columns = table_view_helpers.ComputeUnshownColumns( sorted_issues, mr.col_spec.split(), harmonized_config, features_constants.OTHER_BUILT_IN_COLS) pagination = paginate.ArtifactPagination( mr, sorted_issues, mr.num, GetURLOfHotlist(mr.cnxn, mr.hotlist, services.user), len(sorted_issues)) sort_spec = '%s %s %s' % (mr.group_by_spec, mr.sort_spec, harmonized_config.default_sort_spec) table_data = _MakeTableData(pagination.visible_results, starred_iid_set, mr.col_spec.lower().split(), mr.group_by_spec.lower().split(), issues_users_by_id, tablecell.CELL_FACTORIES, related_issues, harmonized_config, context_for_all_issues, mr.hotlist_id, sort_spec) table_related_dict = { 'column_values': column_values, 'unshown_columns': unshown_columns, 'pagination': pagination, 'is_cross_project': is_cross_project } return table_data, table_related_dict
def CreateHotlistTableData(mr, hotlist_issues, services): """Creates the table data for the hotlistissues table.""" with mr.profiler.Phase('getting stars'): starred_iid_set = set( services.issue_star.LookupStarredItemIDs(mr.cnxn, mr.auth.user_id)) with mr.profiler.Phase('Computing col_spec'): mr.ComputeColSpec(mr.hotlist) issues_list = services.issue.GetIssues( mr.cnxn, [hotlist_issue.issue_id for hotlist_issue in hotlist_issues]) with mr.profiler.Phase('Getting config'): hotlist_issues_project_ids = GetAllProjectsOfIssues( [issue for issue in issues_list]) is_cross_project = len(hotlist_issues_project_ids) > 1 config_list = GetAllConfigsOfProjects(mr.cnxn, hotlist_issues_project_ids, services) harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list) (sorted_issues, hotlist_issues_context, issues_users_by_id) = GetSortedHotlistIssues(mr, hotlist_issues, issues_list, harmonized_config, services) with mr.profiler.Phase("getting related issues"): related_iids = set() results_needing_related = sorted_issues lower_cols = mr.col_spec.lower().split() for issue in results_needing_related: if 'blockedon' in lower_cols: related_iids.update(issue.blocked_on_iids) if 'blocking' in lower_cols: related_iids.update(issue.blocking_iids) if 'mergedinto' in lower_cols: related_iids.add(issue.merged_into) related_issues_list = services.issue.GetIssues(mr.cnxn, list(related_iids)) related_issues = { issue.issue_id: issue for issue in related_issues_list } with mr.profiler.Phase('filtering unviewable issues'): viewable_iids_set = { issue.issue_id for issue in tracker_helpers.GetAllowedIssues( mr, [related_issues.values()], services)[0] } with mr.profiler.Phase('building table'): context_for_all_issues = { issue.issue_id: hotlist_issues_context[issue.issue_id] for issue in sorted_issues } column_values = table_view_helpers.ExtractUniqueValues( mr.col_spec.lower().split(), sorted_issues, issues_users_by_id, harmonized_config, related_issues, hotlist_context_dict=context_for_all_issues) unshown_columns = table_view_helpers.ComputeUnshownColumns( sorted_issues, mr.col_spec.split(), harmonized_config, features_constants.OTHER_BUILT_IN_COLS) url_params = [(name, mr.GetParam(name)) for name in framework_helpers.RECOGNIZED_PARAMS] # We are passing in None for the project_name because we are not operating # under any project. pagination = paginate.ArtifactPagination( sorted_issues, mr.num, mr.GetPositiveIntParam('start'), None, GetURLOfHotlist(mr.cnxn, mr.hotlist, services.user), total_count=len(sorted_issues), url_params=url_params) sort_spec = '%s %s %s' % (mr.group_by_spec, mr.sort_spec, harmonized_config.default_sort_spec) table_data = _MakeTableData( pagination.visible_results, starred_iid_set, mr.col_spec.lower().split(), mr.group_by_spec.lower().split(), issues_users_by_id, tablecell.CELL_FACTORIES, related_issues, viewable_iids_set, harmonized_config, context_for_all_issues, mr.hotlist_id, sort_spec) table_related_dict = { 'column_values': column_values, 'unshown_columns': unshown_columns, 'pagination': pagination, 'is_cross_project': is_cross_project } return table_data, table_related_dict
def testComputeUnshownColumns_FieldDefs(self): search_results = [ fake.MakeTestIssue( 789, 1, 'sum 1', 'New', 111, field_values=[ tracker_bizobj.MakeFieldValue( 5, 74, None, None, None, None, False, phase_id=4), tracker_bizobj.MakeFieldValue( 6, 78, None, None, None, None, False, phase_id=5)], phases=[ tracker_pb2.Phase(phase_id=4, name='goats'), tracker_pb2.Phase(phase_id=5, name='sheep')]), fake.MakeTestIssue( 789, 2, 'sum 2', 'New', 111, field_values=[ tracker_bizobj.MakeFieldValue( 5, 74, None, None, None, None, False, phase_id=3), tracker_bizobj.MakeFieldValue( 6, 77, None, None, None, None, False, phase_id=3)], phases=[ tracker_pb2.Phase(phase_id=3, name='Goats'), tracker_pb2.Phase(phase_id=3, name='Goats-Exp')]), ] shown_cols = ['a', 'b', 'a1', 'a2-approver', 'f3', 'goats.g1', 'sheep.g2'] config = tracker_bizobj.MakeDefaultProjectIssueConfig(789) config.default_col_spec = '' config.well_known_labels = [] config.field_defs = [ tracker_bizobj.MakeFieldDef( 1, 789, 'a1', tracker_pb2.FieldTypes.APPROVAL_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'Tracks review from cows', False), tracker_bizobj.MakeFieldDef( 2, 789, 'a2', tracker_pb2.FieldTypes.APPROVAL_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'Tracks review from chickens', False), tracker_bizobj.MakeFieldDef( 3, 789, 'f3', tracker_pb2.FieldTypes.STR_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'cow names', False), tracker_bizobj.MakeFieldDef( 4, 789, 'f4', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'chicken gobbles', False), tracker_bizobj.MakeFieldDef( 5, 789, 'g1', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'fluff', False, is_phase_field=True), tracker_bizobj.MakeFieldDef( 6, 789, 'g2', tracker_pb2.FieldTypes.INT_TYPE, None, None, False, False, False, None, None, None, False, None, None, None, None, 'poof', False, is_phase_field=True), ] builtin_cols = [] unshown = table_view_helpers.ComputeUnshownColumns( search_results, shown_cols, config, builtin_cols) self.assertEqual(unshown, [ 'a1-approver', 'a2', 'f4', 'goats-exp.g1', 'goats-exp.g2', 'goats.g2', 'sheep.g1'])