120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
"""Service for managing card positioning and reordering"""
|
|
|
|
from app import db
|
|
from app.models import Card
|
|
|
|
|
|
class CardPositionService:
|
|
"""Service for handling card position management"""
|
|
|
|
@staticmethod
|
|
def reorder_cards_in_list(
|
|
list_id: int, moved_card_id: int, new_position: float
|
|
) -> None:
|
|
"""
|
|
Reorder all cards in a list when one card is moved to a new position.
|
|
|
|
Args:
|
|
list_id: The ID of the list containing the cards
|
|
moved_card_id: The ID of the card being moved
|
|
new_position: The new position for the moved card
|
|
"""
|
|
# Get all cards in the list, ordered by their current position
|
|
all_cards = Card.query.filter_by(list_id=list_id).order_by(Card.pos).all()
|
|
|
|
# Find the moved card in the list
|
|
moved_card = None
|
|
other_cards = []
|
|
|
|
for card in all_cards:
|
|
if card.id == moved_card_id:
|
|
moved_card = card
|
|
else:
|
|
other_cards.append(card)
|
|
|
|
if not moved_card:
|
|
return # Card not found in this list
|
|
|
|
# Remove the moved card from other_cards (already done above)
|
|
# Insert the moved card at the new position in other_cards
|
|
other_cards.insert(int(new_position), moved_card)
|
|
|
|
# Update positions for all cards to ensure unique, sequential positions
|
|
for index, card in enumerate(other_cards):
|
|
card.pos = float(index)
|
|
|
|
db.session.commit()
|
|
|
|
@staticmethod
|
|
def reorder_cards_between_lists(
|
|
from_list_id: int, to_list_id: int, moved_card_id: int, new_position: float
|
|
) -> None:
|
|
"""
|
|
Reorder cards when moving a card from one list to another.
|
|
|
|
Args:
|
|
from_list_id: The source list ID
|
|
to_list_id: The destination list ID
|
|
moved_card_id: The ID of the card being moved
|
|
new_position: The new position in the destination list
|
|
"""
|
|
# Reorder source list (remove the card and compact positions)
|
|
source_cards = (
|
|
Card.query.filter_by(list_id=from_list_id)
|
|
.filter(Card.id != moved_card_id)
|
|
.order_by(Card.pos)
|
|
.all()
|
|
)
|
|
|
|
for index, card in enumerate(source_cards):
|
|
card.pos = float(index)
|
|
|
|
# Reorder destination list (insert the card at new position)
|
|
dest_cards = Card.query.filter_by(list_id=to_list_id).order_by(Card.pos).all()
|
|
|
|
# Insert moved card at the specified position
|
|
dest_cards.insert(int(new_position), None) # Placeholder for moved card
|
|
|
|
for index, card in enumerate(dest_cards):
|
|
if card is None:
|
|
# This is where our moved card should go
|
|
moved_card = Card.query.get(moved_card_id)
|
|
if moved_card:
|
|
moved_card.pos = float(index)
|
|
else:
|
|
card.pos = float(index)
|
|
|
|
db.session.commit()
|
|
|
|
@staticmethod
|
|
def get_next_position(list_id: int) -> float:
|
|
"""
|
|
Get the next available position in a list.
|
|
|
|
Args:
|
|
list_id: The ID of the list
|
|
|
|
Returns:
|
|
The next available position (float)
|
|
"""
|
|
last_card = (
|
|
Card.query.filter_by(list_id=list_id).order_by(Card.pos.desc()).first()
|
|
)
|
|
|
|
return float(last_card.pos + 1) if last_card else 0.0
|
|
|
|
@staticmethod
|
|
def ensure_unique_positions(list_id: int) -> None:
|
|
"""
|
|
Ensure all cards in a list have unique, sequential positions.
|
|
Useful for data cleanup.
|
|
|
|
Args:
|
|
list_id: The ID of the list to fix
|
|
"""
|
|
cards = Card.query.filter_by(list_id=list_id).order_by(Card.pos).all()
|
|
|
|
for index, card in enumerate(cards):
|
|
card.pos = float(index)
|
|
|
|
db.session.commit()
|