Skip to content

Commit

Permalink
feat: make stepper bubbles collapse and refine css working
Browse files Browse the repository at this point in the history
  • Loading branch information
EdoStorm96 committed Sep 19, 2024
1 parent 3d74064 commit 9f63896
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 29 deletions.
34 changes: 27 additions & 7 deletions proposals/utils/stepper.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def __init__(
# which item is current
self.request = request
self.items = []
self.current_item = None
self.current_item_parent = None

self.check_all(self.starting_checkers)

def get_context_data(self):
Expand Down Expand Up @@ -84,8 +87,17 @@ def build_stepper(
raise RuntimeError(
"Base layout was never defined for this stepper",
)
# First, insert all items into the layout
# First, insert all items into the layout & let them figure out their
#own styling
for item in self.items:
#Only check item.is_current until there is a current item found
while not self.current_item:
if item.is_current(self.request):
self.current_item = item
self.current_item_ancestor = item.get_ancestor()
else:
break
item.get_css_classes()
self._insert_item(layout, item)
# Second, replace all remaining empty slots in the layout
# by PlaceholderItems
Expand All @@ -96,12 +108,18 @@ def _insert_item(self, layout, new_item):
"""
Inserts a stepper item into a layout, in-place.
"""
# We're only concerned with top-level items, children can sort
# themselves out
if new_item.parent:
return new_item.parent.children.append(
new_item,
)
if not self.current_item:
# We're only concerned with top-level items, children can sort
# themselves out
if new_item.parent:
return new_item.parent.children.append(
new_item,
)
elif new_item.get_ancestor() == self.current_item_ancestor:
if new_item.parent:
return new_item.parent.children.append(
new_item,
)
# Step through the layout looking for empty slots, which are
# represented by tuples of locations and titles
for index, slot in enumerate(layout):
Expand All @@ -120,6 +138,8 @@ def _insert_placeholders(self, layout):
for index, slot in enumerate(layout):
# Skip slots that are already items
if isinstance(slot, StepperItem):
if slot != self.current_item_ancestor:
slot.children = []
continue
# Remaining empty slots are replaced by placeholders
placeholder = PlaceholderItem(
Expand Down
58 changes: 36 additions & 22 deletions proposals/utils/stepper_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __init__(self, stepper, parent=None, title=None, location=None):
self.children = []
self.parent = parent
self.available = False
self.css_classes = ""
# Don't override default location if not provided explicitly
if location:
self.location = location
Expand All @@ -70,30 +71,48 @@ def get_url(self):

def get_errors(self):
return []

def css_classes(
self,
):
classes = []
if self.is_current(self.stepper.request):
classes.append(
"active",
)
return " ".join(classes)

def get_ancestor(self):
"""
Returns the top level parent, or ancestor
"""
ancestor = self
while ancestor.parent:
ancestor = ancestor.parent
return ancestor

def get_family(self):
"""
Returns all items with the same ancestor
"""
family = []
if not self.parent:
return family


def is_current(self, request):
"""
Returns True if this item represents the page the user
is currently on.
is currently on and appends the active class to the item's
css_classes attribute. This gets called when building the stepper,
until is_current returns True.
"""
if request.path == self.get_url():
self.css_classes += "active "
return True
return False

def is_disabled(self):
if not self.get_url():
return True
return False

def get_css_classes(self):
"""
A method to be overwritten by child classes to append to an item's
self.css_classes attribute. This gets called when building the stepper.
"""
pass


class PlaceholderItem(StepperItem):
Expand Down Expand Up @@ -129,16 +148,14 @@ def is_current(self, request):
"""
return False

def css_classes(self):
css_classes = super().css_classes()
def get_css_classes(self):
child_errors = []
for child in self.children:
child_errors += child.get_errors()
if child_errors != []:
css_classes += "incomplete"
self.css_classes += "incomplete"
else:
css_classes += " complete"
return css_classes
self.css_classes += " complete"


class ModelFormChecker(
Expand Down Expand Up @@ -261,14 +278,11 @@ def get_errors(self):
return self.get_checker_errors() or self.model_form.errors
return self.model_form.errors

def css_classes(self):
css_classes = super().css_classes()

def get_css_classes(self):
if self.get_errors():
css_classes += " incomplete"
self.css_classes += " incomplete"
else:
css_classes += " complete"
return css_classes
self.css_classes += " complete"


class UpdateOrCreateChecker(
Expand Down

0 comments on commit 9f63896

Please sign in to comment.