diff options
| author | zousar <[email protected]> | 2026-02-15 23:44:17 -0700 |
|---|---|---|
| committer | zousar <[email protected]> | 2026-02-15 23:44:17 -0700 |
| commit | 81a6d5e29453db761d058b6418044c8cf04a167e (patch) | |
| tree | 89a82f510e002a5c9dcf3852d87e08842dc92def | |
| parent | Restore handling for hard/soft name prefixes (diff) | |
| download | zen-81a6d5e29453db761d058b6418044c8cf04a167e.tar.xz zen-81a6d5e29453db761d058b6418044c8cf04a167e.zip | |
Add support for listing files on oplog entries
| -rw-r--r-- | src/zenserver/frontend/html/pages/entry.js | 119 |
1 files changed, 110 insertions, 9 deletions
diff --git a/src/zenserver/frontend/html/pages/entry.js b/src/zenserver/frontend/html/pages/entry.js index 76afd3e1f..26ea78142 100644 --- a/src/zenserver/frontend/html/pages/entry.js +++ b/src/zenserver/frontend/html/pages/entry.js @@ -76,6 +76,21 @@ export class Page extends ZenPage return null; } + _is_null_io_hash_string(io_hash) + { + if (!io_hash) + return true; + + for (let char of io_hash) + { + if (char != '0') + { + return false; + } + } + return true; + } + async _build_meta(section, entry) { var tree = {} @@ -142,30 +157,34 @@ export class Page extends ZenPage const name = entry.find("key").as_value(); var section = this.add_section(name); + var has_package_data = false; // tree { var tree = entry.find("$tree"); if (tree == undefined) tree = this._convert_legacy_to_tree(entry); - if (tree == undefined) - return this._display_unsupported(section, entry); - - delete tree["$id"]; - - if (Object.keys(tree).length != 0) + if (tree != undefined) { - const sub_section = section.add_section("dependencies"); - this._build_deps(sub_section, tree); + delete tree["$id"]; + + if (Object.keys(tree).length != 0) + { + const sub_section = section.add_section("dependencies"); + this._build_deps(sub_section, tree); + } + has_package_data = true; } } // meta + if (has_package_data) { this._build_meta(section, entry); } // data + if (has_package_data) { const sub_section = section.add_section("data"); const table = sub_section.add_widget( @@ -181,7 +200,7 @@ export class Page extends ZenPage for (const item of pkg_data.as_array()) { - var io_hash, size, raw_size, file_name; + var io_hash = undefined, size = undefined, raw_size = undefined, file_name = undefined; for (const field of item.as_object()) { if (field.is_named("data")) io_hash = field.as_value(); @@ -219,12 +238,94 @@ export class Page extends ZenPage } } + // files + var has_file_data = false; + { + const sub_section = section.add_section("files"); + const table = sub_section.add_widget( + Table, + ["name", "actions"], Table.Flag_PackRight + ); + table.id("filetable"); + for (const field_name of ["files"]) + { + var file_data = entry.find(field_name); + if (file_data == undefined) + continue; + + has_file_data = true; + + for (const item of file_data.as_array()) + { + var io_hash = undefined, cid = undefined, server_path = undefined, client_path = undefined; + for (const field of item.as_object()) + { + if (field.is_named("data")) io_hash = field.as_value(); + else if (field.is_named("id")) cid = field.as_value(); + else if (field.is_named("serverpath")) server_path = field.as_value(); + else if (field.is_named("clientpath")) client_path = field.as_value(); + } + + if (io_hash instanceof Uint8Array) + { + var ret = ""; + for (var x of io_hash) + ret += x.toString(16).padStart(2, "0"); + io_hash = ret; + } + + if (cid instanceof Uint8Array) + { + var ret = ""; + for (var x of cid) + ret += x.toString(16).padStart(2, "0"); + cid = ret; + } + + const row = table.add_row(server_path); + + var base_name = server_path.split("/").pop().split("\\").pop(); + const project = this.get_param("project"); + const oplog = this.get_param("oplog"); + if (this._is_null_io_hash_string(io_hash)) + { + const link = row.get_cell(0).link( + "/" + ["prj", project, "oplog", oplog, cid].join("/") + ); + link.first_child().attr("download", `${cid}_${base_name}`); + + const action_tb = new Toolbar(row.get_cell(-1), true); + action_tb.left().add("copy-id").on_click(async (v) => { + await navigator.clipboard.writeText(v); + }, cid); + } + else + { + const link = row.get_cell(0).link( + "/" + ["prj", project, "oplog", oplog, io_hash].join("/") + ); + link.first_child().attr("download", `${io_hash}_${base_name}`); + + const action_tb = new Toolbar(row.get_cell(-1), true); + action_tb.left().add("copy-hash").on_click(async (v) => { + await navigator.clipboard.writeText(v); + }, io_hash); + } + + } + } + } + // props + if (has_package_data) { const object = entry.to_js_object(); var sub_section = section.add_section("props"); sub_section.add_widget(PropTable).add_object(object); } + + if (!has_package_data && !has_file_data) + return this._display_unsupported(section, entry); } _display_unsupported(section, entry) |