From 8212a50d58c7ef68670ee4266bd89432f3d04219 Mon Sep 17 00:00:00 2001 From: Todd Dembrey <todd.dembrey@torchbox.com> Date: Thu, 10 Jan 2019 15:51:45 +0000 Subject: [PATCH] Update the workflow/phases api to simplify finding phases --- .../funds/templatetags/statusbar_tags.py | 27 ++++++------------- opentech/apply/funds/workflow.py | 23 ++++++++++++++++ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/opentech/apply/funds/templatetags/statusbar_tags.py b/opentech/apply/funds/templatetags/statusbar_tags.py index 01d0fc744..66ccf0c49 100644 --- a/opentech/apply/funds/templatetags/statusbar_tags.py +++ b/opentech/apply/funds/templatetags/statusbar_tags.py @@ -1,35 +1,24 @@ -from collections import defaultdict from django import template register = template.Library() -def find_last_visible_phase(phases, user, current_phase): - last_phase = current_phase - while not last_phase.permissions.can_view(user): - last_phase = phases[last_phase.step - 1][0] - return last_phase - - @register.inclusion_tag('funds/includes/status_bar.html') def status_bar(workflow, current_phase, user, css_class='', same_stage=False): - all_phases = defaultdict(list) - for phase in list(workflow.values()): - all_phases[phase.step].append(phase) + phases = workflow.phases_for(user) - # Grab the first phase for each step - visible only, the display phase - phases = [ - phase for phase, *_ in all_phases.values() - if phase.permissions.can_view(user) - and (not same_stage or phase.stage == current_phase.stage) - ] + if same_stage: + phases = [ + phase for phase in phases + if phase.stage == current_phase.stage + ] if not current_phase.permissions.can_view(user): - current_phase = find_last_visible_phase(all_phases, user, current_phase) + current_phase = workflow.latest_visible(current_phase, user) # Current step not shown for user, move current phase to last good location - elif not all_phases[current_phase.step][0].permissions.can_view(user): + elif not workflow.stepped_phases[current_phase.step][0].permissions.can_view(user): new_phase_list = [] for phase in reversed(phases): if phase.step <= current_phase.step and current_phase not in new_phase_list: diff --git a/opentech/apply/funds/workflow.py b/opentech/apply/funds/workflow.py index e2a1d6261..c8faf7eee 100644 --- a/opentech/apply/funds/workflow.py +++ b/opentech/apply/funds/workflow.py @@ -38,6 +38,29 @@ class Workflow(dict): stages.append(phase.stage) return stages + @property + def stepped_phases(self): + phases = defaultdict(list) + for phase in list(workflow.values()): + all_phases[phase.step].append(phase) + return phases + + def phases_for(self, user): + # Grab the first phase for each step - visible only, the display phase + phases = [ + phase for phase, *_ in self.stepped_phases.values() + if phase.permissions.can_view(user) + ] + + def previous_visible(self, current, user): + """Find the latest phase that the user has view permissions for""" + display_phase = self.stepped_phases[current.step][0] + phases = self.phases_for(user) + index = phases.index(current) + for phase in phases[index - 1::-1]: + if phase.permission.can_view(user): + return phase + class Phase: def __init__(self, name, display, stage, permissions, step, public=None, transitions=dict()): -- GitLab