Skip to main content

Reusable Google-Docs-style share dialog for Datasette (<datasette-acl-share-dialog>)

Project description

datasette-acl-share

A reusable, Google-Docs-style share dialog for Datasette, shipped as a framework-agnostic Svelte 5 custom element: <datasette-acl-share-dialog>.

One component, embedded by every document plugin (paper, places, sheets, …). It is the UI layer over the datasette-acl JSON API — grants, roles, groups, and "general access" wildcards. If datasette-user-profiles is installed the dialog adds people search and avatars; without it, it degrades gracefully to initials chips with no People search.

Usage

Drop the tag anywhere — inside a Svelte/Preact app, or in plain server-rendered HTML (custom elements are just DOM):

<datasette-acl-share-dialog
  resource-type="paper-doc"
  parent="mydb"
  child="42"
  resource-label="Q2 Planning"
></datasette-acl-share-dialog>

The element renders a compact share-icon button; clicking it opens a modal <dialog> (dismiss with the × button, the backdrop, or Esc). The resource is fetched lazily on first open, so a page can carry many share buttons cheaply.

Once open, the dialog shows "people with access" (avatars, role dropdowns, remove buttons), a "General access" section, and an add-box that searches people (profiles) and groups (acl). Each action is its own fetch — grant / update / revoke — matching Google Docs' incremental behaviour. Actors who cannot manage the resource (can_manage: false) get a read-only roster: roles as tags, no add-box, no remove buttons.

Attributes

Attribute Req Purpose
resource-type yes acl resource type, e.g. paper-doc, places-list, sheets-workbook
parent yes resource identity part 1 (e.g. database name)
child resource identity part 2 (e.g. row id); omit for parent-only resources
resource-label display title shown in the dialog header
actor-json current actor as JSON ({"id":"alice","kind":"user"}) — used to mark "(you)"
features comma list of sections to show (people,groups,public); empty/missing = all available
api-base override the acl API prefix (default /-/acl/api)
open when set (any value other than false), open the modal on mount instead of waiting for a trigger click
trigger-label text shown next to the share icon on the trigger button (icon-only if omitted)
disabled when set (any value other than false), disable the trigger so the dialog can't open (e.g. the actor can't share this resource)

Events

The element dispatches bubbling, composed CustomEvents so hosts can react (e.g. paper re-running its SSE subscriber sweep after a revoke):

Event detail
share-granted {principal, id, role}
share-updated {principal, id, role}
share-revoked {principal, id}
share-changed {} — fired after any mutation (coarse)

principal is "actor" or "group"; id is the actor id, group id, or a general-access wildcard (* / _signed_in).

Including the bundle (opt-in)

The bundle is built with and served via datasette-vite. It is not injected site-wide — a host plugin opts in from its own asset hooks so the dialog only loads on pages that use it:

from datasette import hookimpl
from datasette_acl_share import datasette_share_assets

@hookimpl
def extra_js_urls(datasette, request):
    # gate on your own page(s) so it doesn't load everywhere
    if not _is_my_page(request):
        return []
    return datasette_share_assets(datasette)["js"]

@hookimpl
def extra_css_urls(datasette, request):
    if not _is_my_page(request):
        return []
    return datasette_share_assets(datasette)["css"]

The helper returns {"js": [{"url": …, "module": True}], "css": [url, …]}, ready for Datasette's extra_js_urls / extra_css_urls hooks. In datasette-vite dev mode the js list includes the Vite client (HMR) and css is empty — your plugin code is identical in dev and prod. Hosts that own their own Vite build can instead splice the URLs into their page template.

Capability probe

So a host can set features without guessing which optional backends exist:

GET /-/share/capabilities  →  {"people": true, "groups": true, "public": true}

people reflects whether datasette-user-profiles is installed (search + avatars); groups and public are intrinsic to datasette-acl. share_capabilities() is also importable if you prefer to compute the features string server-side.

Embedding in apps

A Svelte app (paper, places, sheets) renders the tag directly — attributes bind, and onshare-* props receive the events:

<datasette-acl-share-dialog
  resource-type="paper-doc"
  parent={dbName}
  child={docId}
  resource-label={docTitle}
  actor-json={JSON.stringify(actor)}
  onshare-revoked={onShareRevoked}
></datasette-acl-share-dialog>

Preact hosts (datasette-comments) and plain Jinja pages embed the same tag unchanged, wiring events with addEventListener.

For a full walkthrough — modelling the acl resource type / actions / roles, seeding grants, gating pages, plus web-component tips and a minimal end-to-end plugin — see docs/integration-guide.md.

Development

just frontend-install   # one-time npm install
just frontend           # production build (writes static/gen + manifest.json)
just dev                # datasette + the sample-docs demo at :5171

# Or with Vite HMR:
just frontend-dev       # terminal 1: vite dev server (port 5180)
just dev-with-hmr       # terminal 2: datasette pointed at the dev server

just dev loads a throwaway demo plugin (tests/sample_plugins, with templates in tests/templates) plus datasette-debug-gotham / datasette-user-profiles / datasette-debug-bar. Visit http://localhost:5171/sample-docs, switch characters with the debug bar (Clark owns doc 1), and exercise the dialog — see CLAUDE.md for the full demo walkthrough.

Built assets (datasette_acl_share/static/, manifest.json) are gitignored and produced by the build.

Tests

npm --prefix frontend run test    # vitest (node + browser suites)
npm --prefix frontend run check   # svelte-check + tsc
uv run pytest                     # Python: asset helper + capability probe

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

datasette_acl_share-0.0.1a2.tar.gz (42.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

datasette_acl_share-0.0.1a2-py3-none-any.whl (38.7 kB view details)

Uploaded Python 3

File details

Details for the file datasette_acl_share-0.0.1a2.tar.gz.

File metadata

  • Download URL: datasette_acl_share-0.0.1a2.tar.gz
  • Upload date:
  • Size: 42.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for datasette_acl_share-0.0.1a2.tar.gz
Algorithm Hash digest
SHA256 d309c8eb7bda2606178827f63d4e7e381f04e0a32ee583c28e8111e354b03915
MD5 753eecd5b4df58c8199caf631e4b7d09
BLAKE2b-256 98a28c4060eca9571005680e8cd0cbb0d0293c18010691943246e047aae3e509

See more details on using hashes here.

File details

Details for the file datasette_acl_share-0.0.1a2-py3-none-any.whl.

File metadata

  • Download URL: datasette_acl_share-0.0.1a2-py3-none-any.whl
  • Upload date:
  • Size: 38.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for datasette_acl_share-0.0.1a2-py3-none-any.whl
Algorithm Hash digest
SHA256 ae8ca8a2be07db673151ccae22eb4bd581f6dd17cad53b1e66a4aec0dc089b66
MD5 4e85fc0d61c1a38fbc3895a50b026b8e
BLAKE2b-256 b2370633722be4eb2fc6a7e302217c0d84adfe9c608f31c8283cd578d18effe7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page