Skip to content

UI for associating clubs to different elements of the system #34

Description

@jonesd

Problem

Access control is scattered and inconsistent across the system. Works have read_club/edit_club, annotations just got is_private: bool, links have no per-element ACL, and each feature has its own ad-hoc UI. We need a unified, reusable component for club-based access control.

Proposal

Build a reusable ClubSelector React component with adapters for each use case. Any element that needs access control uses the same UX pattern.

Component: ClubSelector

A dropdown/combobox that:

  • Shows current access level as a label ("Public", "Private", "Members of X")
  • Lists clubs the current session belongs to (fetched via club_who_am_i)
  • Supports single-club selection (read/edit club) or multi-club (annotation visibility)
  • Returns selected club ID(s) to the parent via callback
  • Includes a "Public" option (no club restriction) and "Private" option (creator only)

Hook up via adapters:

Feature Current state Wire ops needed
Work read club DocumentSettings has basic UI work_set_read_club (exists)
Work edit club Same panel work_set_edit_club (exists)
Work history club Separate setting work_set_history_club (exists)
Annotation visibility Just added is_private: bool Extend to visible_to_clubs: Option<Vec<BeId>>
Link visibility No per-link ACL New: link_set_visibility
Club default clubs ClubSetDefaultReadClub etc. All exist

Backend changes needed:

  1. Generalize annotation visibility — replace is_private: bool with visible_to_clubs: Option<Vec<BeId>> on OtreeAnnotation. Mapping: None = public, Some([]) = private (creator only), Some([ids]) = visible to specific clubs. Backward compatible: is_private: true deserializes to Some([]).

  2. Add annotation_set_visibility op — toggle/change visibility on existing annotations.

  3. Add link_set_visibility op (optional, future) — per-link access control.

Existing infrastructure:

  • ClubGet, ClubNames, ClubWhoAmI ops already return club lists and membership
  • WorkSetReadClub, WorkSetEditClub, WorkSetHistoryClub ops already exist
  • Clubs have display_name(), name(), membership lists
  • The KeyMaster system resolves session authority to club IDs
  • Named clubs with passwords for authenticated users
  • Personal clubs for individual identity

Frontend:

  • ClubSelector component (~150 lines, reusable)
  • Adapter for each panel (DocumentSettings, AnnotationPanel, LinkPanel, etc.)
  • Fetch club list via existing clubWhoAmI() client method
  • Single-select vs multi-select modes
  • Intuitive labels: "Everyone", "Just me", "My team", custom club names

Scope

  • Effort: M (frontend-heavy, backend ops mostly exist)
  • No breaking changes to existing wire protocol
  • The ClubSelector can be built first, then adapters added incrementally

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions