feat(scripts/data-resources): merge tree + add parent_path filter

- Backend: GET /api/v1/data-resources accepts parent_path; LIKE
  '{ws_id}/%/{escaped}/%' AND NOT LIKE '{ws_id}/%/{escaped}/%/%' on
  StorageObjects.object_key (workspace-wide, escapes _ and %, mirrors
  list_scripts parent_path semantics). 13 new tests in
  test_resources.py (helper unit / SQL compile / SQLite behavioral).
- Frontend: listResources gains parentPath arg, propagated through
  WorkspaceBoundApi + AuthContext binding. WorkspaceTreeGroup title
  count and ScriptExplorer header count now include dataResources.
  memberScriptGroups backfills data-only owners so users with only
  data resources still render a group. loadDataResources accepts an
  optional parentPath, default empty preserves prior behavior.
This commit is contained in:
tao.chen
2026-08-21 12:36:43 +08:00
parent a9b682c1a1
commit 48fe49df3b
7 changed files with 296 additions and 9 deletions
@@ -94,6 +94,14 @@ export function ScriptExplorer({
byOwner.set(item.owner_user_id, list);
}
// data-only owner(只有数据资源、没有 scripts 的用户)也要出现在分组里,
// 因为 data resources 与 scripts 共享同一棵目录树。
for (const ownerUserId of dataByOwner.keys()) {
if (!byOwner.has(ownerUserId)) {
byOwner.set(ownerUserId, []);
}
}
const groups: {
user: AuthUser | null;
scripts: ScriptItem[];
@@ -143,7 +151,7 @@ export function ScriptExplorer({
<div className="explorer__header">
<div>
<h2></h2>
<span>{scripts.length} </span>
<span>{scripts.length + dataResources.length} </span>
</div>
<div className="explorer__actions">
<button