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('///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) )