╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───────────────╮ │src/ui/Repo/Settings.zig│ ╰────────────────────────╯ ╭─────────────────────────────────────╮ │29 patch_role: ?evt.Repo.Role, │ │30 hash_kind: hash.HashKind, │ │31 // the sub tab the route names │ │32 -view: enum { settings, roles }, │ │33 -roles: Roles, │ │32 +view: enum { settings, members },│ │33 +members: Members, │ │34 │ │35 const Self = @This(); │ │36 │ ╰─────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │37 -// the tab role choices, in the order the form shows them │ │38 -const role_choices = [_]?evt.Repo.Role{ null, .owner, .write, .read }; │ │37 +// the tab role choices, in the order the form shows them. no owners-only│ │38 +// choice, so anyone who can push may push events for every tab. │ │39 +const role_choices = [_]?evt.Repo.Role{ null, .write, .read }; │ │40 │ │41 const role_labels = blk: { │ │42 var labels: [role_choices.len][]const u8 = undefined; │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────╮ │47 pub fn roleLabel(role_maybe: ?evt.Repo.Role) []const u8 {│ │48 const role = role_maybe orelse return "nobody"; │ │49 return switch (role) { │ │49 - .owner => "owners", │ │50 - .write => "collaborators", │ │50 + .owner, .write => "members", │ │51 .read => "anybody", │ │52 }; │ │53 } │ ╰─────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────╮ │60 return error.InvalidRole; │ │61 } │ │62 │ │63 -// the repo settings and user roles sub tabs over their content│ │63 +// the repo settings and members sub tabs over their content │ │64 pub const View = struct { │ │65 box: wgt.Box(ui.Widget), │ │66 │ ╰───────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │75 var header = try wgt.Box(ui.Widget).init(allocator, .{ .border = null, .direction = .horiz }); │ │76 errdefer header.deinit(allocator); │ │77 const on_tab = switch (session.data.current_page) { │ │78 - .repo_settings, .repo_roles => true, │ │78 + .repo_settings, .repo_members => true, │ │79 else => false, │ │80 }; │ │81 - const routes = [_]?ui.RoutablePage{ ui.RoutablePage.repoSettingsRoute(data.identity), ui.RoutablePage.repoRolesRoute(data.identity, 0) }; │ │82 - for ([_]@FieldType(Self, "view"){ .settings, .roles }, [_][]const u8{ "repo settings", "user roles" }, routes) |view, label, route| { │ │81 + const routes = [_]?ui.RoutablePage{ ui.RoutablePage.repoSettingsRoute(data.identity), ui.RoutablePage.repoMembersRoute(data.identity, 0) };│ │82 + for ([_]@FieldType(Self, "view"){ .settings, .members }, [_][]const u8{ "repo settings", "members" }, routes) |view, label, route| { │ │83 var tab = try wgt.TextBox.init(allocator, label, .{ .border = .hidden, .round_corners = true, .wrap_kind = .none }); │ │84 errdefer tab.deinit(allocator); │ │85 tab.getFocus().mode = .all; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │100 try stack.children.put(allocator, form.getFocus().id, .{ .repo_settings_form = form }); │ │101 } │ │102 { │ │103 - var roles = try Roles.View.init(allocator, &data.roles, session); │ │104 - errdefer roles.deinit(allocator); │ │105 - try stack.children.put(allocator, roles.getFocus().id, .{ .repo_roles = roles }); │ │103 + var members = try Members.View.init(allocator, &data.members, session); │ │104 + errdefer members.deinit(allocator); │ │105 + try stack.children.put(allocator, members.getFocus().id, .{ .repo_members = members }); │ │106 } │ │107 stack.getFocus().child_id = stack.children.keys()[@backingInt(data.view)]; │ │108 try box.children.put(allocator, stack.getFocus().id, .{ .widget = .{ .stack = stack }, .rect = null, .min_size = null });│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ added ────────────────╮ │src/ui/Repo/Members.zig│ ╰───────────────────────╯ ╭ changed ────────╮ │src/ui/widget.zig│ ╰─────────────────╯ ╭──────────────────────────────────────────────────╮ │66 repo_undo: ui.Repo.Undo.View, │ │67 repo_settings: ui.Repo.Settings.View, │ │68 repo_settings_form: ui.Repo.Settings.Form,│ │69 - repo_roles: ui.Repo.Roles.View, │ │69 + repo_members: ui.Repo.Members.View, │ │70 repo_comment: ui.Repo.Comment.Item, │ │71 copyable_text: CopyableText, │ │72 patch_source: ui.Repo.Patches.Source, │ ╰──────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │119 // whether moving up should return to the page header │ │120 pub fn atTop(self: *Widget, root_focus: *Focus) bool { │ │121 return switch (self.*) { │ │122 - inline .home_about, .home_users, .user_repos, .flow_box_scroll, .new_repo, .new_user, .user_login, .user_notifications, .quit, .repo_files, .repo_commits, .diff_view, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_settings, .repo_settings_form, .repo_roles, .user_keys => |*view| view.atTop(), │ │122 + inline .home_about, .home_users, .user_repos, .flow_box_scroll, .new_repo, .new_user, .user_login, .user_notifications, .quit, .repo_files, .repo_commits, .diff_view, .repo_refs, .repo_issues, .repo_patches, .repo_discussions, .repo_events, .repo_undo, .repo_settings, .repo_settings_form, .repo_members, .user_keys => |*view| view.atTop(),│ │123 inline .repo_patch_detail, .user_settings => |*view| view.atTop(root_focus), │ │124 else => false, │ │125 }; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/web.zig│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │173 .addkey => handleUserKeyAdd(io, request, allocator, base, server.admin_repo_path, server.users_dir, server.session_store), │ │174 .removekey => handleUserKeyRemove(io, request, allocator, base, server.admin_repo_path, server.users_dir, server.session_store),│ │175 .settings => handleRepoSettings(io, request, allocator, path, host), │ │176 - .grant => handleRoles(io, request, allocator, base, host, .grant), │ │177 - .revoke => handleRoles(io, request, allocator, base, host, .revoke), │ │178 - .promote => handleRoles(io, request, allocator, base, host, .promote), │ │179 - .demote => handleRoles(io, request, allocator, base, host, .demote), │ │176 + .grant => handleMembers(io, request, allocator, base, host, .grant), │ │177 + .revoke => handleMembers(io, request, allocator, base, host, .revoke), │ │178 + .promote => handleMembers(io, request, allocator, base, host, .promote), │ │179 + .demote => handleMembers(io, request, allocator, base, host, .demote), │ │180 .new => handleNew(io, request, allocator, base, host), │ │181 .edit => handleEdit(io, request, allocator, base, host), │ │182 .remove => handleRemove(io, request, allocator, base, host), │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯