models

URL bundle and reorder utility functions for sortable queues.

source

SortableQueueUrls


def SortableQueueUrls(
    reorder:str, remove:str, clear:str
)->None:

URL endpoints for sortable queue HTMX operations.

Reorder Utilities


source

reorder_by_keys


def reorder_by_keys(
    items:List, # Current item list
    new_key_order:List, # Keys in desired order (from Sortable.js form data)
    key_fn:Callable, # Function to extract key from item
)->List: # Reordered item list

Reorder items to match the key order from Sortable.js form data.


source

reorder_by_direction


def reorder_by_direction(
    items:List, # Current item list
    item_key:str, # Key of item to move
    direction:str, # "up" or "down"
    key_fn:Callable, # Function to extract key from item
)->List: # Reordered item list

Move an item up or down by swapping with its neighbor.

Tests

# URL bundle
urls = SortableQueueUrls(reorder="/queue/reorder", remove="/queue/remove", clear="/queue/clear")
assert urls.reorder == "/queue/reorder"
assert urls.remove == "/queue/remove"
assert urls.clear == "/queue/clear"

# Test data
key_fn = lambda item: item["id"]
items = [{"id": "a", "name": "Alpha"}, {"id": "b", "name": "Beta"}, {"id": "c", "name": "Charlie"}]

# reorder_by_keys — normal reorder
result = reorder_by_keys(items, ["c", "a", "b"], key_fn)
assert [key_fn(i) for i in result] == ["c", "a", "b"]

# reorder_by_keys — empty order returns copy
result = reorder_by_keys(items, [], key_fn)
assert [key_fn(i) for i in result] == ["a", "b", "c"]

# reorder_by_keys — missing key in order appends at end
result = reorder_by_keys(items, ["b", "c"], key_fn)
assert [key_fn(i) for i in result] == ["b", "c", "a"]

# reorder_by_keys — extra key in order is ignored
result = reorder_by_keys(items, ["c", "x", "a", "b"], key_fn)
assert [key_fn(i) for i in result] == ["c", "a", "b"]

# reorder_by_direction — move down
result = reorder_by_direction(items, "a", "down", key_fn)
assert [key_fn(i) for i in result] == ["b", "a", "c"]

# reorder_by_direction — move up
result = reorder_by_direction(items, "c", "up", key_fn)
assert [key_fn(i) for i in result] == ["a", "c", "b"]

# reorder_by_direction — can't move first item up
result = reorder_by_direction(items, "a", "up", key_fn)
assert [key_fn(i) for i in result] == ["a", "b", "c"]

# reorder_by_direction — can't move last item down
result = reorder_by_direction(items, "c", "down", key_fn)
assert [key_fn(i) for i in result] == ["a", "b", "c"]

# reorder_by_direction — unknown key returns unchanged
result = reorder_by_direction(items, "x", "down", key_fn)
assert [key_fn(i) for i in result] == ["a", "b", "c"]

print("All models tests passed")