Skip to content

Sharing: restructure the share UI to invite-first, with "Make public" secondary #59

Description

@Adron

Product change to match

Per /help/documents: "You no longer set Public with a separate toggle in the editor. Whether a document is public is now controlled entirely inside the Share window." The window leads with Invite people and offers Make public below, with a copy-link row appearing once public.

The app currently exposes isPublic on the document/list editor and treats share links as the primary sharing mechanism — the inverse of the product's current model.

Acceptance criteria

  • One shared Share window for lists and documents: Invite people first, Make public second.
  • The public toggle is removed from the document/list editors and lives only in the Share window.
  • A copy-link row appears only when the item is public.
  • Copy explains that inviting keeps the item private.

Activity

  1. Adron commented on Sep 16, 2026

    @Adron
    MemberAuthor

    ⚠️ The role vocabulary in this issue is wrong — the API does not accept Read-only / Edit / Admin

    I wrote these issues from /help/documents, which describes three permission levels as Read-only, Edit and Admin. Those are display names. The API rejects them. Verified live 2026-09-16 on a throwaway list:

    role=read-only     -> 400 {"error":"Invalid role. Must be watcher, collaborator, or manager"}
    role=edit          -> 400 {"error":"Invalid role. Must be watcher, collaborator, or manager"}
    role=admin         -> 400 {"error":"Invalid role. Must be watcher, collaborator, or manager"}
    
    role=watcher       -> 201 {"email":"…","role":"watcher","expiresAt":null,"url":"…/lists/invite/OG72S9Ee…"}
    role=collaborator  -> 201 {"email":"…","role":"collaborator","expiresAt":null,"url":"…"}
    role=manager       -> 201 {"email":"…","role":"manager","expiresAt":null,"url":"…"}
    

    So the wire values are watcher / collaborator / manager, and any UI needs an explicit mapping to the documented labels:

    Wire value Help-doc label Can
    watcher Read-only view content only
    collaborator Edit change content, but not rename, change public/private, or move
    manager Admin also rename, switch visibility, move, delete

    Don't send the display names, and don't show the wire values to users.

    Other live findings from #55/#56 (PRs #168/#169) that affect these issues

    The invite envelopes are asymmetric, which forces a read-after-write:

    POST   …/invites  -> 201 {email, role, expiresAt, url}     ← url, NO token
    GET    …/invites  -> 200 {invites:[{email, role, expiresAt, accepted, createdAt, token}]}  ← token, NO url
    DELETE …/invites/{token} -> 200 {"revoked":true}
    

    Revoke is keyed by token, which the create response doesn't return — so creating an invite must be followed by a GET to obtain a revocable handle. Copy-link rebuilds the URL from the token.

    role works despite the published OpenAPI request schema omitting it — that schema lists only email + expiresAt. Another case of the spec being thinner than reality; /help/api/sharing is right and the spec is wrong.

    Error shapes: invalid email → 400 "A valid email address is required"; unknown token → 404 "Invite not found or access denied" (note: not-found and not-permitted are deliberately indistinguishable).

    Ownership envelopes differ between domains — lists nest the object under data, documents under document; both carry userId, which neither ListSummary nor DocumentSummary models.

    customerStatus values are free / subscriber / subscriber:monthly / subscriber:annual — any non-free value grants access, so don't compare against the literal "subscriber".

    An undocumented notify:false on invite create is accepted (201) but not echoed back. It was deliberately not exposed in the UI because there's no way to confirm it actually suppresses the email — which is exactly what #58's "Email this person" toggle needs. Confirming that flag is the blocker for #58's notify toggle, and it needs a mailbox you control to verify.

    Still unverified for #57

    The claim/accept side (/api/{lists|documents}/invite/{token}) is cookie-session-only per the docs and needs a second verified account, so it is unimplemented. That's the substance of #57.

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

    P2Deptharea:sharingArea: sharingparityWeb/API feature-parity work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions