aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzousar <[email protected]>2026-02-17 20:21:26 -0700
committerzousar <[email protected]>2026-02-17 20:21:26 -0700
commitd1324d607e54e2e97d666a2d1ece9ac9495d1eb1 (patch)
tree295efabe4c0d808aabc6149a4ca03db1869ccf1d
parentAdded custom page for cook.artifacts (diff)
downloadzen-d1324d607e54e2e97d666a2d1ece9ac9495d1eb1.tar.xz
zen-d1324d607e54e2e97d666a2d1ece9ac9495d1eb1.zip
Make files table in entry.js paginated and searchable
-rw-r--r--src/zenserver/frontend/html/pages/entry.js210
1 files changed, 170 insertions, 40 deletions
diff --git a/src/zenserver/frontend/html/pages/entry.js b/src/zenserver/frontend/html/pages/entry.js
index dca3a5c25..13d5e44e7 100644
--- a/src/zenserver/frontend/html/pages/entry.js
+++ b/src/zenserver/frontend/html/pages/entry.js
@@ -26,6 +26,9 @@ export class Page extends ZenPage
this._indexer = this.load_indexer(project, oplog);
+ this._files_index_start = Number(this.get_param("files_start", 0)) || 0;
+ this._files_index_count = Number(this.get_param("files_count", 50)) || 0;
+
this._build_page();
}
@@ -253,20 +256,13 @@ 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("files");
+ if (file_data != undefined)
{
- var file_data = entry.find(field_name);
- if (file_data == undefined)
- continue;
-
has_file_data = true;
+ // Extract files into array
+ this._files_data = [];
for (const item of file_data.as_array())
{
var io_hash = undefined, cid = undefined, server_path = undefined, client_path = undefined;
@@ -294,37 +290,26 @@ export class Page extends ZenPage
cid = ret;
}
- const row = table.add_row(server_path);
+ this._files_data.push({
+ server_path: server_path,
+ client_path: client_path,
+ io_hash: io_hash,
+ cid: cid
+ });
+ }
- 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);
- }
+ this._files_index_max = this._files_data.length;
- }
+ const sub_section = section.add_section("files");
+ this._build_files_nav(sub_section);
+
+ this._files_table = sub_section.add_widget(
+ Table,
+ ["name", "actions"], Table.Flag_PackRight
+ );
+ this._files_table.id("filetable");
+
+ this._build_files_table(this._files_index_start);
}
}
@@ -419,4 +404,149 @@ export class Page extends ZenPage
params.set("opkey", opkey);
window.location.search = params;
}
+
+ _build_files_nav(section)
+ {
+ const nav = section.add_widget(Toolbar);
+ const left = nav.left();
+ left.add("|<") .on_click(() => this._on_files_next_prev(-10e10));
+ left.add("<<") .on_click(() => this._on_files_next_prev(-10));
+ left.add("prev").on_click(() => this._on_files_next_prev( -1));
+ left.add("next").on_click(() => this._on_files_next_prev( 1));
+ left.add(">>") .on_click(() => this._on_files_next_prev( 10));
+ left.add(">|") .on_click(() => this._on_files_next_prev( 10e10));
+
+ left.sep();
+ for (var count of [10, 25, 50, 100])
+ {
+ var handler = (n) => this._on_files_change_count(n);
+ left.add(count).on_click(handler, count);
+ }
+
+ const right = nav.right();
+ right.add(Friendly.sep(this._files_index_max));
+
+ right.sep();
+ var search_input = right.add("search:", "label").tag("input");
+ search_input.on("change", (x) => this._search_files(x.inner().value), search_input);
+ }
+
+ _build_files_table(index)
+ {
+ this._files_index_count = Math.max(this._files_index_count, 1);
+ index = Math.min(index, this._files_index_max - this._files_index_count);
+ index = Math.max(index, 0);
+
+ const project = this.get_param("project");
+ const oplog = this.get_param("oplog");
+
+ const end_index = Math.min(index + this._files_index_count, this._files_index_max);
+
+ this._files_table.clear(index);
+ for (var i = index; i < end_index; i++)
+ {
+ const file_item = this._files_data[i];
+ const row = this._files_table.add_row(file_item.server_path);
+
+ var base_name = file_item.server_path.split("/").pop().split("\\").pop();
+ if (this._is_null_io_hash_string(file_item.io_hash))
+ {
+ const link = row.get_cell(0).link(
+ "/" + ["prj", project, "oplog", oplog, file_item.cid].join("/")
+ );
+ link.first_child().attr("download", `${file_item.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);
+ }, file_item.cid);
+ }
+ else
+ {
+ const link = row.get_cell(0).link(
+ "/" + ["prj", project, "oplog", oplog, file_item.io_hash].join("/")
+ );
+ link.first_child().attr("download", `${file_item.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);
+ }, file_item.io_hash);
+ }
+ }
+
+ this.set_param("files_start", index);
+ this.set_param("files_count", this._files_index_count);
+ this._files_index_start = index;
+ }
+
+ _on_files_change_count(value)
+ {
+ this._files_index_count = parseInt(value);
+ this._build_files_table(this._files_index_start);
+ }
+
+ _on_files_next_prev(direction)
+ {
+ var index = this._files_index_start + (this._files_index_count * direction);
+ index = Math.max(0, index);
+ this._build_files_table(index);
+ }
+
+ _search_files(needle)
+ {
+ if (needle.length == 0)
+ {
+ this._build_files_table(this._files_index_start);
+ return;
+ }
+ needle = needle.trim().toLowerCase();
+
+ this._files_table.clear(this._files_index_start);
+
+ const project = this.get_param("project");
+ const oplog = this.get_param("oplog");
+
+ var added = 0;
+ const truncate_at = this.get_param("searchmax") || 250;
+ for (const file_item of this._files_data)
+ {
+ if (!file_item.server_path.toLowerCase().includes(needle))
+ continue;
+
+ const row = this._files_table.add_row(file_item.server_path);
+
+ var base_name = file_item.server_path.split("/").pop().split("\\").pop();
+ if (this._is_null_io_hash_string(file_item.io_hash))
+ {
+ const link = row.get_cell(0).link(
+ "/" + ["prj", project, "oplog", oplog, file_item.cid].join("/")
+ );
+ link.first_child().attr("download", `${file_item.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);
+ }, file_item.cid);
+ }
+ else
+ {
+ const link = row.get_cell(0).link(
+ "/" + ["prj", project, "oplog", oplog, file_item.io_hash].join("/")
+ );
+ link.first_child().attr("download", `${file_item.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);
+ }, file_item.io_hash);
+ }
+
+ if (++added >= truncate_at)
+ {
+ this._files_table.add_row("...truncated");
+ break;
+ }
+ }
+ }
}