Skip to content

Latest commit

 

History

History
130 lines (101 loc) · 6.41 KB

modules.md

File metadata and controls

130 lines (101 loc) · 6.41 KB

Modules

The studio is a shell plus a set of modules. A module contributes routes, navigation, dashboard widgets and other extension points, and is switched on per deployment.

Two conditions must both hold for an optional module to appear:

  1. It is enabled in configuration: features.<id>.enabled is true.
  2. The connected server reports the feature it requires, read from the installed-feature catalogue.

A module that fails the second test is hidden entirely, with no navigation entry and no routes, even when enabled. This is why a studio pointed at a minimal Elsa server shows fewer entries.

What ships

Core modules

Always enabled; the configuration flag is ignored.

Module Id Routes Purpose
Dashboard dashboard / Throughput, status breakdown, per-workflow activity.
Workflow definitions workflow-definitions /workflows/definitions, …/:definitionId/edit List and the visual editor.
Workflow instances workflow-instances /workflows/instances, …/:id/view List and the run viewer.

Optional modules

Module Id Requires server feature Routes
Environments environments none Header picker only
Labels labels Elsa.Labels /labels
Secrets secrets Elsa.Secrets /security/secrets, …/:name
Security security Elsa.Identity /security/users, /security/roles
Alterations alterations Elsa.Alterations /alterations/plans, …/:id
User tasks user-tasks Elsa.UserTasks /workflows/user-tasks, …/:taskId
Settings settings none /settings
Appearance appearance none /settings/appearance
Console logs diagnostics-console-logs Elsa.Diagnostics.ConsoleLogs.ShellFeatures.ConsoleLogs /diagnostics/console
Structured logs diagnostics-structured-logs Elsa.Diagnostics.StructuredLogs.ShellFeatures.StructuredLogs /diagnostics/structured-logs

Notes on individual modules

Secrets manages credentials that workflows reference by name. Values are write-only: they are submitted on create or rotate and never read back. The module also contributes a secret picker to activity inputs, so a workflow refers to a secret rather than embedding one.

User tasks is the human-task inbox: claim, assign, release, complete and cancel, with dynamic forms resolved by the server. Masked fields are hidden until explicitly revealed, including in the raw payload views.

Alterations applies changes to running instances, such as migrating to a newer version, modifying a variable, scheduling or cancelling an activity. It contributes row actions to the instances list and the instance viewer, and can bulk-retry faulted instances.

Settings owns the /settings landing page but stores nothing itself. Other modules contribute destinations to it; Appearance is the built-in example. The Settings entry only appears once at least one module contributes a section.

Adding a module

New extensions use the SDK v1 Preview and export register(api). The weather sample imports only the four public packages and is verified against packed artifacts by pnpm test:packages. Feature packages explains the RCL layout, server discovery, independent assets and opt-in hosting.

The imported modules use the SDK's declarative defineModule() adapter. Their source currently has this layout:

dotnet/modules/Elsa.ReactStudio.<Feature>/Client/
  index.tsx     the defineModule export
  routes.ts     route patterns, kept separate so components can import them without a cycle
  api.ts        endpoint group built from the shared HTTP client
  hooks.ts      TanStack Query hooks
  pages/        route components
  components/   module-local components
export const labelsModule = defineModule({
  id: "labels",                                   // the key in config.features
  name: "Labels",
  requiresServerFeatures: ["Elsa.Labels"],        // hidden when the backend lacks it
  routes: [{ path: "/labels", component: LabelsPage, title: "Labels", permissions: [{ resource: "labels", verb: "view" }] }],
  nav: [{ id: "labels", label: "Labels", href: "/labels", icon: Tag, group: NavGroups.administration.id, order: 200 }],
  extensions: { workflowPropertiesTabs: [...], instanceRowActions: [...], dashboardWidgets: [...] },
});

Then:

  1. Export register from Client/entry.tsx and register its descriptor in the module's CShells feature. Add first-party builds to module-catalog.json. The adapter preserves each module's route declaration priority. Explicit route order overrides it; equal priorities use stable module and slot IDs, independent of load order.
  2. Add "<id>": { "enabled": true } to studio.config.json.
  3. Use the permission types and checks from the public SDK/auth packages.

Rules

  • Routes are matched by the History API router through the module registry, so enabling or disabling a module is enough to add or remove its routes.
  • Cross-module UI goes through extensions and useExtensions(kind). Never import another module's pages. Shared code belongs in the four public workspace packages.
  • Query keys start with useQueryScope(), the active server URL, so switching environments never mixes caches.
  • Build pages from the shared building blocks (PageHeader, DataTable, SearchInput, SimpleSelect, useConfirm, Timestamp) so lists look and behave alike.

Extension points

The specialized UI-hint editors document the built-in date/time, dynamic outcomes, HTTP status codes and workflow-input controls and their server encodings.

A module can contribute to other parts of the studio without either side importing the other:

Extension Where it appears
dashboardWidgets Dashboard zones.
workflowPropertiesTabs The workflow definition properties pane.
activityTabs The activity properties panel.
definitionRowActions, instanceRowActions, instanceViewerActions List rows and the instance viewer header.
headerItems The app header, like the environment picker.
uiHints Activity input editors keyed by UI hint, like the secret picker.
settingsSections Cards on the Settings landing page.
Provider A context provider wrapped around the whole app.

See Architecture for the full contract.