230 lines
7.6 KiB
Python
230 lines
7.6 KiB
Python
from flask import Blueprint, render_template, request
|
|
|
|
from .exceptions import exception_handler
|
|
from ..minifigure_list import BrickMinifigureList
|
|
from ..pagination_helper import get_pagination_config, build_pagination_context, get_request_params
|
|
from ..part import BrickPart
|
|
from ..part_list import BrickPartList
|
|
from ..set_list import BrickSetList, set_metadata_lists
|
|
from ..set_owner_list import BrickSetOwnerList
|
|
from ..sql import BrickSQL
|
|
|
|
part_page = Blueprint('part', __name__, url_prefix='/parts')
|
|
|
|
|
|
# Index
|
|
@part_page.route('/', methods=['GET'])
|
|
@exception_handler(__file__)
|
|
def list() -> str:
|
|
# Get filter parameters from request
|
|
owner_id = request.args.get('owner', 'all')
|
|
color_id = request.args.get('color', 'all')
|
|
theme_id = request.args.get('theme', 'all')
|
|
year = request.args.get('year', 'all')
|
|
search_query, sort_field, sort_order, page = get_request_params()
|
|
|
|
# Get pagination configuration
|
|
per_page, is_mobile = get_pagination_config('parts')
|
|
use_pagination = per_page > 0
|
|
|
|
if use_pagination:
|
|
# PAGINATION MODE - Server-side pagination with search
|
|
parts, total_count = BrickPartList().all_filtered_paginated(
|
|
owner_id=owner_id,
|
|
color_id=color_id,
|
|
theme_id=theme_id,
|
|
year=year,
|
|
search_query=search_query,
|
|
page=page,
|
|
per_page=per_page,
|
|
sort_field=sort_field,
|
|
sort_order=sort_order
|
|
)
|
|
|
|
pagination_context = build_pagination_context(page, per_page, total_count, is_mobile)
|
|
else:
|
|
# ORIGINAL MODE - Single page with all data for client-side search
|
|
parts = BrickPartList().all_filtered(owner_id, color_id, theme_id, year)
|
|
pagination_context = None
|
|
|
|
# Get list of owners for filter dropdown
|
|
owners = BrickSetOwnerList.list()
|
|
|
|
# Prepare context for dependent filters
|
|
filter_context = {}
|
|
if owner_id != 'all' and owner_id:
|
|
filter_context['owner_id'] = owner_id
|
|
|
|
# Get list of colors for filter dropdown
|
|
colors = BrickSQL().fetchall('part/colors/list', **filter_context)
|
|
|
|
# Get list of themes for filter dropdown
|
|
from ..theme_list import BrickThemeList
|
|
theme_list = BrickThemeList()
|
|
themes_data = BrickSQL().fetchall('part/themes/list', **filter_context)
|
|
themes = []
|
|
for theme_data in themes_data:
|
|
theme = theme_list.get(theme_data['theme_id'])
|
|
themes.append({
|
|
'theme_id': theme_data['theme_id'],
|
|
'theme_name': theme.name if theme else f"Theme {theme_data['theme_id']}"
|
|
})
|
|
|
|
# Get list of years for filter dropdown
|
|
years = BrickSQL().fetchall('part/years/list', **filter_context)
|
|
|
|
template_context = {
|
|
'table_collection': parts,
|
|
'owners': owners,
|
|
'selected_owner': owner_id,
|
|
'colors': colors,
|
|
'selected_color': color_id,
|
|
'themes': themes,
|
|
'selected_theme': theme_id,
|
|
'years': years,
|
|
'selected_year': year,
|
|
'search_query': search_query,
|
|
'use_pagination': use_pagination,
|
|
'current_sort': sort_field,
|
|
'current_order': sort_order
|
|
}
|
|
|
|
if pagination_context:
|
|
template_context['pagination'] = pagination_context
|
|
|
|
return render_template('parts.html', **template_context)
|
|
|
|
|
|
|
|
# Problem
|
|
@part_page.route('/problem', methods=['GET'])
|
|
@exception_handler(__file__)
|
|
def problem() -> str:
|
|
# Get filter parameters from request
|
|
owner_id = request.args.get('owner', 'all')
|
|
color_id = request.args.get('color', 'all')
|
|
theme_id = request.args.get('theme', 'all')
|
|
year = request.args.get('year', 'all')
|
|
storage_id = request.args.get('storage', 'all')
|
|
tag_id = request.args.get('tag', 'all')
|
|
search_query, sort_field, sort_order, page = get_request_params()
|
|
|
|
# Get pagination configuration
|
|
per_page, is_mobile = get_pagination_config('problems')
|
|
use_pagination = per_page > 0
|
|
|
|
if use_pagination:
|
|
# PAGINATION MODE - Server-side pagination with search and filters
|
|
parts, total_count = BrickPartList().problem_paginated(
|
|
owner_id=owner_id,
|
|
color_id=color_id,
|
|
theme_id=theme_id,
|
|
year=year,
|
|
storage_id=storage_id,
|
|
tag_id=tag_id,
|
|
search_query=search_query,
|
|
page=page,
|
|
per_page=per_page,
|
|
sort_field=sort_field,
|
|
sort_order=sort_order
|
|
)
|
|
|
|
pagination_context = build_pagination_context(page, per_page, total_count, is_mobile)
|
|
else:
|
|
# ORIGINAL MODE - Single page with all data for client-side search
|
|
parts = BrickPartList().problem_filtered(owner_id, color_id, theme_id, year, storage_id, tag_id)
|
|
pagination_context = None
|
|
|
|
# Get list of owners for filter dropdown
|
|
owners = BrickSetOwnerList.list()
|
|
|
|
# Prepare context for dependent filters
|
|
filter_context = {}
|
|
if owner_id != 'all' and owner_id:
|
|
filter_context['owner_id'] = owner_id
|
|
|
|
# Get list of colors for filter dropdown (problem parts only)
|
|
colors = BrickSQL().fetchall('part/colors/list_problem', **filter_context)
|
|
|
|
# Get list of themes for filter dropdown (problem parts only)
|
|
from ..theme_list import BrickThemeList
|
|
theme_list = BrickThemeList()
|
|
themes_data = BrickSQL().fetchall('part/themes/list_problem', **filter_context)
|
|
themes = []
|
|
for theme_data in themes_data:
|
|
theme = theme_list.get(theme_data['theme_id'])
|
|
themes.append({
|
|
'theme_id': theme_data['theme_id'],
|
|
'theme_name': theme.name if theme else f"Theme {theme_data['theme_id']}"
|
|
})
|
|
|
|
# Get list of years for filter dropdown (problem parts only)
|
|
years = BrickSQL().fetchall('part/years/list_problem', **filter_context)
|
|
|
|
# Get list of storages for filter dropdown (problem parts only)
|
|
storages = BrickSQL().fetchall('part/storages/list_problem', **filter_context)
|
|
|
|
# Get list of tags for filter dropdown (problem parts only)
|
|
tags = BrickSQL().fetchall('part/tags/list_problem', **filter_context)
|
|
|
|
return render_template(
|
|
'problem.html',
|
|
table_collection=parts,
|
|
pagination=pagination_context,
|
|
search_query=search_query,
|
|
sort_field=sort_field,
|
|
sort_order=sort_order,
|
|
use_pagination=use_pagination,
|
|
owners=owners,
|
|
colors=colors,
|
|
selected_owner=owner_id,
|
|
selected_color=color_id,
|
|
themes=themes,
|
|
selected_theme=theme_id,
|
|
years=years,
|
|
selected_year=year,
|
|
storages=storages,
|
|
selected_storage=storage_id,
|
|
tags=tags,
|
|
selected_tag=tag_id
|
|
)
|
|
|
|
|
|
# Part details
|
|
@part_page.route('/<part>/<int:color>/details', methods=['GET']) # noqa: E501
|
|
@exception_handler(__file__)
|
|
def details(*, part: str, color: int) -> str:
|
|
brickpart = BrickPart().select_generic(part, color)
|
|
|
|
return render_template(
|
|
'part.html',
|
|
item=brickpart,
|
|
sets_using=BrickSetList().using_part(
|
|
part,
|
|
color
|
|
),
|
|
sets_missing=BrickSetList().missing_part(
|
|
part,
|
|
color
|
|
),
|
|
sets_damaged=BrickSetList().damaged_part(
|
|
part,
|
|
color
|
|
),
|
|
minifigures_using=BrickMinifigureList().using_part(
|
|
part,
|
|
color
|
|
),
|
|
minifigures_missing=BrickMinifigureList().missing_part(
|
|
part,
|
|
color
|
|
),
|
|
minifigures_damaged=BrickMinifigureList().damaged_part(
|
|
part,
|
|
color
|
|
),
|
|
different_color=BrickPartList().with_different_color(brickpart),
|
|
similar_prints=BrickPartList().from_print(brickpart),
|
|
**set_metadata_lists(as_class=True)
|
|
)
|