feat: Tabular seamless infinite scroll instead of page buttons

Tabular handles paging client-side — scroll to bottom auto-loads more.
Record_view renders each model as a card (icon + name + description).
Removed all server-side pagination logic from the template.
This commit is contained in:
yumoqing 2026-07-29 15:13:13 +08:00
parent 10280f60f1
commit 659af09a89

View File

@ -1,41 +1,25 @@
{% set providerid = params_kw.get('providerid', '') %} {% set providerid = params_kw.get('providerid', '') %}
{% set catelogid = params_kw.get('catelogid', '') %} {% set catelogid = params_kw.get('catelogid', '') %}
{% set search = params_kw.get('search', '') %} {% set search = params_kw.get('search', '') %}
{% set page = (params_kw.get('page', '1') | int) %}
{% set page_size = 20 %}
{% set all_data = get_plaza_models(providerid, catelogid, search) %}
{% set total = all_data | length %}
{% set total_pages = ((total + page_size - 1) / page_size) | int %}
{% set start = (page - 1) * page_size %}
{% set end = [start + page_size, total] | min %}
{% set data = all_data[start:end] %}
{% set base = '/llmage/model_plaza.ui' %}
{% set ns = namespace(first=true) %}
{ {
"widgettype": "VBox", "widgettype": "VBox",
"options": {"css": "filler", "width": "100%", "height": "100%"}, "options": {"css": "filler", "width": "100%", "height": "100%"},
"subwidgets": [ "subwidgets": [
{ {
"widgettype": "VScrollPanel", "widgettype": "Tabular",
"options": {"css": "filler", "flex": "1", "width": "100%"},
"subwidgets": [
{
"widgettype": "DynamicColumn",
"options": { "options": {
"css": "plaza-grid", "css": "filler",
"width": "100%", "width": "100%",
"col_cwidth": 22, "height": "100%",
"col_cgap": 1 "data_url": "{{entire_url('api/get_plaza_models.dspy')}}?providerid={{providerid}}&catelogid={{catelogid}}&search={{search}}",
}, "pagerows": 20,
"subwidgets": [ "record_view": {
{% for llm in data %}
{% if not ns.first %},{% endif %}
{
"widgettype": "VBox", "widgettype": "VBox",
"options": { "options": {
"css": "card plaza-card", "css": "card plaza-card",
"width": "100%", "width": "100%",
"cheight": 14 "cheight": 10,
"marginBottom": "8px"
}, },
"subwidgets": [ "subwidgets": [
{ {
@ -44,53 +28,23 @@
"subwidgets": [ "subwidgets": [
{ {
"widgettype": "Svg", "widgettype": "Svg",
"options": {"rate": 1.5, "url": "{{entire_url('/appbase/show_icon.dspy')}}?id={{llm.iconid}}"} "options": {"rate": 1.5, "url": "{{entire_url('/appbase/show_icon.dspy')}}?id=${iconid}"}
}, },
{ {
"widgettype": "Title6", "widgettype": "Title6",
"options": {"text": "{{llm.name}}"} "options": {"text": "${name}"}
} }
] ]
}, },
{
"widgettype": "VScrollPanel",
"options": {"css": "filler", "flex": "1"},
"subwidgets": [
{ {
"widgettype": "Text", "widgettype": "Text",
"options": { "options": {
"height": "auto", "height": "auto",
"text": {{json.dumps(llm.description, ensure_ascii=False)}}, "text": "${description}",
"wrap": true, "wrap": true,
"halign": "left" "halign": "left"
} }
} }
{% if llm.pricing_display %}
{% if llm.pricing_display is string %}
{% set pricing_items = [llm.pricing_display] %}
{% else %}
{% set pricing_items = llm.pricing_display %}
{% endif %}
,{
"widgettype": "VBox",
"options": {"css": "filler"},
"subwidgets": [
{% for pt in pricing_items %}
{
"widgettype": "Text",
"options": {
"text": {{json.dumps(pt, ensure_ascii=False)}},
"wrap": true,
"halign": "left",
"css": "pricing-text"
}
}{% if not loop.last %},{% endif %}
{% endfor %}
]
}
{% endif %}
]
}
], ],
"binds": [ "binds": [
{ {
@ -99,7 +53,7 @@
"actiontype": "urlwidget", "actiontype": "urlwidget",
"target": "PopupWindow", "target": "PopupWindow",
"popup_options": { "popup_options": {
"title": "{{llm.name}}", "title": "${name}",
{% if int(params_kw._is_mobile or 0) %} {% if int(params_kw._is_mobile or 0) %}
"width": "100%", "width": "100%",
"height": "100%" "height": "100%"
@ -109,47 +63,13 @@
{% endif %} {% endif %}
}, },
"options": { "options": {
"params": {"id": "{{llm.id}}"}, "params": {"id": "${id}"},
"url": "{{entire_url('./llm_dialog.ui')}}" "url": "{{entire_url('./llm_dialog.ui')}}"
} }
} }
] ]
} }
{% set ns.first = false %} }
{% endfor %}
]
} }
] ]
}{% if total_pages > 1 %},
{% endif %}
{% if total_pages > 1 %}
{
"widgettype": "HBox",
"options": {"cheight": 3, "gap": "8px", "alignItems": "center", "justifyContent": "center", "padding": "8px 0"},
"subwidgets": [
{% if page > 1 %}
{
"widgettype": "Button",
"options": {"label": "上一页", "cwidth": 10},
"binds": [{
"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "location.href='{{base}}?providerid={{providerid}}&catelogid={{catelogid}}&search={{search}}&page={{page - 1}}';"
}]
},
{% endif %}
{"widgettype": "Text", "options": {"text": "{{page}}/{{total_pages}} ({{total}}个)"}},
{% if page < total_pages %}
{
"widgettype": "Button",
"options": {"label": "下一页", "cwidth": 10},
"binds": [{
"wid": "self", "event": "click", "actiontype": "script", "target": "self",
"script": "location.href='{{base}}?providerid={{providerid}}&catelogid={{catelogid}}&search={{search}}&page={{page + 1}}';"
}]
}
{% endif %}
]
}
{% endif %}
]
} }