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" audiences. 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.

The share dialog open on a document, showing a person and two groups with role dropdowns and a General access control

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) and a "General access" section. The last row of the roster is an inline add-row: one unified box searches people (profiles) and groups (acl) together, stages your picks as pills, then a role dropdown + Add confirm them — all in place, no separate add panel. 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-row, no remove buttons.

The inline add-row's search open, results split into People and Groups sub-sections A searched person staged as a removable pill inside the add-row, with a role dropdown and Add button, before confirming
One search, people and groups together Picks staged inline with a role, before hitting Add
The General access control set to 'Anyone signed in' with a Viewer role
General access for public audiences

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", "group", or "public"; id is the actor id, group id, or a general-access audience name (everyone / authenticated).

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-resources 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-resources, switch characters with the debug bar (start as Clark — he manages one of every type), 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.1a5.tar.gz (45.3 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.1a5-py3-none-any.whl (40.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: datasette_acl_share-0.0.1a5.tar.gz
  • Upload date:
  • Size: 45.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","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.1a5.tar.gz
Algorithm Hash digest
SHA256 f18b6d7cd5b2f5ba25c90578c5a3f9ca5d0d32c5bc748854b9159d8b4ead9506
MD5 8d63bcbad4374412e638460a6160dcfb
BLAKE2b-256 351768b523cac6a632336e7284be72d2a07e542c63265d96662235f5bd50e4b1

See more details on using hashes here.

File details

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

File metadata

  • Download URL: datasette_acl_share-0.0.1a5-py3-none-any.whl
  • Upload date:
  • Size: 40.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","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.1a5-py3-none-any.whl
Algorithm Hash digest
SHA256 289f9e0549a0b8e7cc62e6cb9f9dd0bf36e80f47f9463ea26c3fc7b3cc40f162
MD5 009be6650e2f74ff4e08a73e73d84cfe
BLAKE2b-256 6a66cdb4e46076505b1d388ce67c7030c18911b273c1f4eaeff5df7505b65f9b

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