feat(dashboard): the UGC page replaces UGC Search

The UGC Search page and the UGC page searched the same things (owner,
account, property, the name and description a player gave a model, LOT,
UGC / blueprint id) with the same SQL. The UGC page's lists are now the
one search:

- models' List view has a Where column: placed on a property (with the
  name given there and a link to the model in the property's 3D view),
  in a mail or in the creator's inventories, or not found
  (/api/ugc?where=1, UgcLinks::Whereabouts as before)
- owners link to their character and, with accounts_view, account
- while searching, the kind buttons say how many models and how many
  cars and rockets match (/api/ugc "matches")
- /ugc_search?q= redirects to /ugc?view=list&q=; the menu's UGC Search
  entry is now UGC, which opens the UGC page (it was only under Server
  Admin, for ugc_manage)
- References lose their Find button (Where it is has the same) and name
  the inventory a build is in

The ugc-search page and script are removed; /api/ugc_links/search stays
for API users.

Check: the menu's UGC entry; an old /ugc_search?q= link opens the UGC
list with the search filled in; owner:, account:, property:, name:,
lot: and id: searches, and the counts on the kind buttons; the Where
column's links (property, 3D, character, account).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 06:14:47 -05:00
parent e159d7b768
commit fd141c232b
9 changed files with 91 additions and 140 deletions

View File

@@ -13,7 +13,7 @@
{% if can.accounts_view %}<a href="/accounts" class="list-group-item list-group-item-action{% if current_page == "accounts" %} active{% endif %}">Accounts</a>{% endif %}
{% if can.characters_view %}<a href="/characters" class="list-group-item list-group-item-action{% if current_page == "characters" %} active{% endif %}">Characters</a>{% endif %}
{% if can.properties_view %}<a href="/properties" class="list-group-item list-group-item-action{% if current_page == "properties" %} active{% endif %}">Properties</a>{% endif %}
{% if can.properties_view %}<a href="/ugc_search" class="list-group-item list-group-item-action{% if current_page == "ugc_search" %} active{% endif %}">UGC Search</a>{% endif %}
{% if can.properties_view %}<a href="/ugc" class="list-group-item list-group-item-action{% if current_page == "ugc" %} active{% endif %}">UGC</a>{% endif %}
</div>
{% set inboxPages = ["moderation", "player_reports", "bug_reports"] %}
@@ -120,8 +120,8 @@
</div>
{% endif %}
{% set adminPages = ["settings", "settings_history", "permissions", "tasks", "play_keys", "backups", "webhooks", "client_assets", "ugc"] %}
{% if can.settings or can.permissions_manage or can.grants_manage or can.tasks_view or can.play_keys_manage or can.backups or can.webhooks or can.client_files or can.ugc_manage %}
{% set adminPages = ["settings", "settings_history", "permissions", "tasks", "play_keys", "backups", "webhooks", "client_assets"] %}
{% if can.settings or can.permissions_manage or can.grants_manage or can.tasks_view or can.play_keys_manage or can.backups or can.webhooks or can.client_files %}
<div class="nav-group">
<button class="nav-group-toggle" type="button" data-bs-toggle="collapse" data-bs-target="#nav-admin" aria-expanded="{% if current_page in adminPages %}true{% else %}false{% endif %}" aria-controls="nav-admin">
Server Admin<span class="nav-group-dot" title="Something in here needs attention"></span>
@@ -134,7 +134,6 @@
{% if can.play_keys_manage %}<a href="/play_keys" class="list-group-item list-group-item-action{% if current_page == "play_keys" %} active{% endif %}">Play Keys</a>{% endif %}
{% if can.backups %}<a href="/backups" class="list-group-item list-group-item-action{% if current_page == "backups" %} active{% endif %}">Backups</a>{% endif %}
{% if can.webhooks %}<a href="/webhooks" class="list-group-item list-group-item-action{% if current_page == "webhooks" %} active{% endif %}">Webhooks</a>{% endif %}
{% if can.ugc_manage %}<a href="/ugc" class="list-group-item list-group-item-action{% if current_page == "ugc" %} active{% endif %}">UGC Server</a>{% endif %}
{% if can.client_files %}<a href="/client_assets" class="list-group-item list-group-item-action{% if current_page == "client_assets" %} active{% endif %}">Client Files</a>{% endif %}
</div>
</div>

View File

@@ -1,35 +0,0 @@
{% extends "base.jinja2" %}
{% block title %}UGC Search - DarkflameServer{% endblock %}
{% block content %}
<div id="ugcSearchPage" data-query="{{ query }}" data-can-accounts="{% if can.accounts_view %}1{% endif %}">
<div class="mb-3">
<h2 class="mb-1">UGC Search</h2>
<p class="text-body-secondary mb-0">Find the models, cars and rockets players built, what the UGC server made of them and where they are.
A number finds ids (the UGC / blueprint id, a placed model's object id, a property, character or account id) and LOTs;
text finds creators' character and account names, property names and the names players gave their models.
Search one field with <code>owner:</code>, <code>property:</code>, <code>model:</code>, <code>id:</code> or <code>lot:</code>.</p>
</div>
<form class="mb-3" id="ugcSearchForm" role="search">
<div class="input-group">
<input type="search" class="form-control" id="ugcSearchInput" placeholder="Name, id or LOT" aria-label="Search players' creations" autocomplete="off" maxlength="100">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</form>
<div id="ugcSearchStatus" class="text-body-secondary small mb-2"></div>
<div class="card">
<div class="table-responsive">
<table class="table table-sm align-middle mb-0 table-stack">
<thead><tr><th></th><th>Creation</th><th>Made by</th><th>Where</th><th>UGC server</th></tr></thead>
<tbody id="ugcSearchRows"><tr><td colspan="5" class="text-body-secondary">Type something to search.</td></tr></tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="/js/ugc-links.js"></script>
<script src="/js/ugc-search.js"></script>
{% endblock %}

View File

@@ -8,7 +8,8 @@
<h2 class="mb-1">UGC Server</h2>
<p class="text-body-secondary mb-0">The UGC server makes a mesh and an icon for every model players build, and icons for their cars and rockets,
and serves them to the game client. New and changed models are picked up by themselves; a model that fails is tried a few times, then left
as failed until it's made again from here. See <code>docs/UgcServer.md</code>.</p>
as failed until it's made again from here. The search finds creations by owner, account, property, the name players gave them, LOT or id,
and the List view says where each one is. See <code>docs/UgcServer.md</code>.</p>
</div>
<div class="row g-2 mb-3" id="counts"></div>
@@ -75,7 +76,7 @@
<div id="gallery" class="ugc-gallery mb-2"></div>
<div class="card d-none" id="listCard"><div class="card-body p-2">
<div id="modelTableBox"><table class="table table-sm align-middle mb-0 w-100 table-stack" id="ugcModelTable">
<thead><tr><th>Icon</th><th>ID</th><th>Owner</th><th>State</th><th>Made</th><th>Took</th><th>CPU</th><th>RAM (est.)</th><th>Saved</th><th>Size</th><th>File</th><th></th></tr></thead></table></div>
<thead><tr><th>Icon</th><th>ID</th><th>Owner</th><th>State</th><th>Made</th><th>Took</th><th>CPU</th><th>RAM (est.)</th><th>Saved</th><th>Size</th><th>File</th><th>Where</th><th></th></tr></thead></table></div>
<div id="assemblyTableBox" class="d-none"><table class="table table-sm align-middle mb-0 w-100 table-stack" id="ugcAssemblyTable">
<thead><tr><th>Icon</th><th>ID</th><th>Owner</th><th>State</th><th>Made</th><th>Took</th><th>CPU</th><th>RAM (est.)</th><th>Size</th><th>File</th><th>Where</th><th></th></tr></thead></table></div>
</div></div>
@@ -172,7 +173,7 @@
<div class="card-header py-2 small fw-semibold d-flex flex-wrap align-items-center gap-2">References <span class="text-body-secondary fw-normal">the builds that use these modules</span>
<input type="search" class="form-control form-control-sm ms-auto" style="max-width: 16rem" id="refSearch" placeholder="Owner, account, property or id" aria-label="Search the builds"></div>
<div class="card-body p-2"><table class="table table-sm small align-middle mb-0 w-100" id="refTable">
<thead><tr><th>Build (blueprint id)</th><th>Owner</th><th>Account</th><th>State</th><th>Made</th><th>Where it is</th><th></th></tr></thead></table></div>
<thead><tr><th>Build (blueprint id)</th><th>Owner</th><th>Account</th><th>State</th><th>Made</th><th>Where it is</th></tr></thead></table></div>
</div>
</div>
</div></div>