╭ changed ─────────────╮ │src/ui/Repo/Issues.zig│ ╰──────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │301 if (!try set.contains(order_key)) return error.NotFound; │ │302 conflicts_root = order_key; │ │303 } else { │ │326 - // the named issue must be in its windowed set (a label url can name │ │327 - // an issue that doesn't carry the label). │ │328 - const set = (switch (issue_event.event.status) { │ │329 - .open => open_set, │ │330 - .closed => closed_set, │ │331 - }) orelse return error.NotFound; │ │332 - if (!try set.contains(order_key)) return error.NotFound; │ │333 - if (assignee_set) |assignee_issues| if (!try assignee_issues.contains(order_key)) return error.NotFound;│ │304 + // the named issue must be in every set its window intersects (a │ │305 + // filtered url can name an issue the filters leave out). │ │306 + const sets = switch (issue_event.event.status) { │ │307 + .open => open_sets, │ │308 + .closed => closed_sets, │ │309 + }; │ │310 + if (!try thread.inEverySet(DB, sets, order_key)) return error.NotFound; │ │311 │ │312 switch (issue_event.event.status) { │ │313 .open => open_root = order_key, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │338 } │ │339 │ │340 const thread_comments_start = if (empty.comment_id.len == 0) comments_start else 0; │ │364 - const open_window = try thread.loadWindow(Self, .issue, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_issue, open_set, open_root, conflict_set, empty.selected_id, thread_comments_start, empty.search, assignee_set, viewer); │ │365 - const closed_window = try thread.loadWindow(Self, .issue, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_issue, closed_set, closed_root, conflict_set, empty.selected_id, thread_comments_start, empty.search, assignee_set, viewer); │ │366 - const conflicts_window = try thread.loadWindow(Self, .issue, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_issue, conflict_set, conflicts_root, conflict_set, empty.selected_id, thread_comments_start, null, null, viewer); │ │341 + const open_window = try thread.loadWindow(Self, .issue, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_issue, open_sets, open_root, conflict_set, empty.selected_id, thread_comments_start, filters.words, viewer); │ │342 + const closed_window = try thread.loadWindow(Self, .issue, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_issue, closed_sets, closed_root, conflict_set, empty.selected_id, thread_comments_start, filters.words, viewer); │ │343 + const conflicts_window = try thread.loadWindow(Self, .issue, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_issue, if (conflict_set) |*set| set[0..1] else &.{}, conflicts_root, conflict_set, empty.selected_id, thread_comments_start, "", viewer);│ │344 if (view == .conflicts and conflicts_window.count > 0) resolved_view = .conflicts; │ │345 │ │346 const comment_page = if (empty.comment_id.len == 0) │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────╮ │352 │ │353 return .{ │ │354 .identity = empty.identity, │ │378 - .label = empty.label, │ │379 - .assignee = empty.assignee, │ │380 - .assignee_found = assignee_found, │ │355 .search = empty.search, │ │356 + .assignee_unknown = empty.assignee_unknown,│ │357 .selected_id = empty.selected_id, │ │358 .comment_id = empty.comment_id, │ │359 .comments_start = comments_start, │ ╰────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │388 │ │389 // tabs switching between the issues page's views │ │390 pub fn initHeader(allocator: std.mem.Allocator, session: *ui.Session, data: *const Self) !Header { │ │416 - var header = try Header.init(allocator, session, data.search, .{ │ │417 - .label = if (data.assignee_found) " assignee " else " assignee (not found) ", │ │418 - .text = std.Uri.percentDecodeInPlace(try session.page_arena.allocator().dupe(u8, data.assignee)), │ │419 - }); │ │391 + var header = try Header.init(allocator, session, data.search, if (data.assignee_unknown) " search (assignee not found) " else " search ");│ │392 errdefer header.deinit(allocator); │ │393 const selected_index = View.viewIndex(data.view); │ │394 const page_selected = std.meta.activeTag(session.data.current_page) == .repo_issues; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │396 // a list tab per status, labeled with its listing's issue count │ │397 const status_labels = [_][]const u8{ open_tab_label, closed_tab_label }; │ │398 for ([_]evt.Issue.Status{ .open, .closed }, status_labels, 0..) |status, status_label, index| { │ │427 - const route = try thread.searchRoute(ui.RoutablePage.withEncodedAssignee(ui.RoutablePage.repoIssuesRoute(data.identity, status, data.label, ""), data.assignee), data.search);│ │399 + const route = try thread.searchRoute(ui.RoutablePage.repoIssuesRoute(data.identity, status, ""), data.search); │ │400 const link = try ui.inPageTabLink(session, route, page_selected and selected_index == index); │ │401 var label_buf: [64]u8 = undefined; │ │402 const label = try thread.countLabel(&label_buf, status_label, data.window(status).*); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │405 │ │406 // labels tab │ │407 { │ │436 - const labels_route = try thread.searchRoute(ui.RoutablePage.withEncodedAssignee(ui.RoutablePage.repoThreadLabelsRoute(.issue, data.identity, data.label), data.assignee), data.search);│ │408 + const labels_route = try thread.searchRoute(ui.RoutablePage.repoThreadLabelsRoute(.issue, data.identity), data.search); │ │409 const labels_link = try ui.inPageTabLink(session, labels_route, page_selected and selected_index == View.viewIndex(.labels)); │ │410 try header.addTab(allocator, labels_tab_label, labels_link, View.viewIndex(.labels)); │ │411 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯