@tai42/studio-sdk 25.0.1 → 26.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -26
- package/dist/components/action-menu.d.ts +30 -0
- package/dist/components/action-menu.d.ts.map +1 -0
- package/dist/components/action-menu.js +101 -0
- package/dist/components/action-menu.js.map +1 -0
- package/dist/components/agent-picker.d.ts +22 -0
- package/dist/components/agent-picker.d.ts.map +1 -0
- package/dist/components/agent-picker.js +17 -0
- package/dist/components/agent-picker.js.map +1 -0
- package/dist/components/channel-picker.d.ts +27 -0
- package/dist/components/channel-picker.d.ts.map +1 -0
- package/dist/components/channel-picker.js +26 -0
- package/dist/components/channel-picker.js.map +1 -0
- package/dist/components/components.css +226 -8
- package/dist/components/confirm-dialog.d.ts +3 -1
- package/dist/components/confirm-dialog.d.ts.map +1 -1
- package/dist/components/confirm-dialog.js +2 -2
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/execution-key-picker.d.ts +26 -10
- package/dist/components/execution-key-picker.d.ts.map +1 -1
- package/dist/components/execution-key-picker.js +134 -15
- package/dist/components/execution-key-picker.js.map +1 -1
- package/dist/components/extension-combo-builder.d.ts +7 -7
- package/dist/components/extension-combo-builder.d.ts.map +1 -1
- package/dist/components/extension-combo-builder.js +42 -16
- package/dist/components/extension-combo-builder.js.map +1 -1
- package/dist/components/extension-combo-parts.d.ts +13 -11
- package/dist/components/extension-combo-parts.d.ts.map +1 -1
- package/dist/components/extension-combo-parts.js +10 -19
- package/dist/components/extension-combo-parts.js.map +1 -1
- package/dist/components/extension-config-editor.d.ts +33 -0
- package/dist/components/extension-config-editor.d.ts.map +1 -0
- package/dist/components/extension-config-editor.js +190 -0
- package/dist/components/extension-config-editor.js.map +1 -0
- package/dist/components/extension-grouping.d.ts +4 -41
- package/dist/components/extension-grouping.d.ts.map +1 -1
- package/dist/components/extension-grouping.js +1 -48
- package/dist/components/extension-grouping.js.map +1 -1
- package/dist/components/extension-picker.d.ts +4 -3
- package/dist/components/extension-picker.d.ts.map +1 -1
- package/dist/components/extension-picker.js +6 -6
- package/dist/components/extension-picker.js.map +1 -1
- package/dist/components/fleet-report.d.ts +8 -3
- package/dist/components/fleet-report.d.ts.map +1 -1
- package/dist/components/fleet-report.js +12 -2
- package/dist/components/fleet-report.js.map +1 -1
- package/dist/components/holder-kinds.d.ts +18 -0
- package/dist/components/holder-kinds.d.ts.map +1 -0
- package/dist/components/holder-kinds.js +41 -0
- package/dist/components/holder-kinds.js.map +1 -0
- package/dist/components/holder-list.d.ts +58 -0
- package/dist/components/holder-list.d.ts.map +1 -0
- package/dist/components/holder-list.js +77 -0
- package/dist/components/holder-list.js.map +1 -0
- package/dist/components/icons/index.d.ts +1 -1
- package/dist/components/icons/index.d.ts.map +1 -1
- package/dist/components/icons/index.js +1 -1
- package/dist/components/icons/index.js.map +1 -1
- package/dist/components/icons/nav-map.d.ts.map +1 -1
- package/dist/components/icons/nav-map.js +1 -3
- package/dist/components/icons/nav-map.js.map +1 -1
- package/dist/components/icons/nav-marks.d.ts +0 -4
- package/dist/components/icons/nav-marks.d.ts.map +1 -1
- package/dist/components/icons/nav-marks.js +0 -4
- package/dist/components/icons/nav-marks.js.map +1 -1
- package/dist/components/named-list-picker.d.ts +39 -0
- package/dist/components/named-list-picker.d.ts.map +1 -0
- package/dist/components/named-list-picker.js +61 -0
- package/dist/components/named-list-picker.js.map +1 -0
- package/dist/components/named-list-test-utils.d.ts +23 -0
- package/dist/components/named-list-test-utils.d.ts.map +1 -0
- package/dist/components/named-list-test-utils.js +33 -0
- package/dist/components/named-list-test-utils.js.map +1 -0
- package/dist/components/recycle-roll.d.ts +23 -0
- package/dist/components/recycle-roll.d.ts.map +1 -0
- package/dist/components/recycle-roll.js +47 -0
- package/dist/components/recycle-roll.js.map +1 -0
- package/dist/components/stepper.d.ts +28 -0
- package/dist/components/stepper.d.ts.map +1 -0
- package/dist/components/stepper.js +33 -0
- package/dist/components/stepper.js.map +1 -0
- package/dist/components/subject-section.d.ts +2 -1
- package/dist/components/subject-section.d.ts.map +1 -1
- package/dist/components/subject-section.js +10 -5
- package/dist/components/subject-section.js.map +1 -1
- package/dist/components/tokens.css +31 -41
- package/dist/components/tokens.d.ts +3 -4
- package/dist/components/tokens.d.ts.map +1 -1
- package/dist/components/tokens.js +5 -13
- package/dist/components/tokens.js.map +1 -1
- package/dist/components/tool-picker-parts.d.ts +5 -1
- package/dist/components/tool-picker-parts.d.ts.map +1 -1
- package/dist/components/tool-picker-parts.js +8 -6
- package/dist/components/tool-picker-parts.js.map +1 -1
- package/dist/components/tool-picker.d.ts +77 -2
- package/dist/components/tool-picker.d.ts.map +1 -1
- package/dist/components/tool-picker.js +87 -29
- package/dist/components/tool-picker.js.map +1 -1
- package/dist/components/version-history-panel.d.ts +7 -1
- package/dist/components/version-history-panel.d.ts.map +1 -1
- package/dist/components/version-history-panel.js +2 -2
- package/dist/components/version-history-panel.js.map +1 -1
- package/dist/components/version-history-rows.d.ts +4 -2
- package/dist/components/version-history-rows.d.ts.map +1 -1
- package/dist/components/version-history-rows.js +14 -2
- package/dist/components/version-history-rows.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +7 -0
- package/dist/errors.js.map +1 -1
- package/dist/hooks/useApi.d.ts +524 -197
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/dist/hooks/useCapabilities.d.ts +43 -10
- package/dist/hooks/useCapabilities.d.ts.map +1 -1
- package/dist/hooks/useCapabilities.js +39 -10
- package/dist/hooks/useCapabilities.js.map +1 -1
- package/dist/index.d.ts +25 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -6
- package/dist/index.js.map +1 -1
- package/dist/marketplace-install/env-var-fields.d.ts +17 -0
- package/dist/marketplace-install/env-var-fields.d.ts.map +1 -0
- package/dist/marketplace-install/env-var-fields.js +22 -0
- package/dist/marketplace-install/env-var-fields.js.map +1 -0
- package/dist/marketplace-install/index.d.ts +18 -0
- package/dist/marketplace-install/index.d.ts.map +1 -0
- package/dist/marketplace-install/index.js +8 -0
- package/dist/marketplace-install/index.js.map +1 -0
- package/dist/marketplace-install/install-env.d.ts +21 -0
- package/dist/marketplace-install/install-env.d.ts.map +1 -0
- package/dist/marketplace-install/install-env.js +22 -0
- package/dist/marketplace-install/install-env.js.map +1 -0
- package/dist/marketplace-install/install-mount.d.ts +42 -0
- package/dist/marketplace-install/install-mount.d.ts.map +1 -0
- package/dist/marketplace-install/install-mount.js +62 -0
- package/dist/marketplace-install/install-mount.js.map +1 -0
- package/dist/marketplace-install/install-report.d.ts +14 -0
- package/dist/marketplace-install/install-report.d.ts.map +1 -0
- package/dist/marketplace-install/install-report.js +19 -0
- package/dist/marketplace-install/install-report.js.map +1 -0
- package/dist/marketplace-install/install-shell.d.ts +34 -0
- package/dist/marketplace-install/install-shell.d.ts.map +1 -0
- package/dist/marketplace-install/install-shell.js +32 -0
- package/dist/marketplace-install/install-shell.js.map +1 -0
- package/dist/marketplace-install/mount-install.d.ts +41 -0
- package/dist/marketplace-install/mount-install.d.ts.map +1 -0
- package/dist/marketplace-install/mount-install.js +90 -0
- package/dist/marketplace-install/mount-install.js.map +1 -0
- package/dist/marketplace-install/plugin-detail.d.ts +17 -0
- package/dist/marketplace-install/plugin-detail.d.ts.map +1 -0
- package/dist/marketplace-install/plugin-detail.js +41 -0
- package/dist/marketplace-install/plugin-detail.js.map +1 -0
- package/dist/marketplace-install/plugin-install.d.ts +27 -0
- package/dist/marketplace-install/plugin-install.d.ts.map +1 -0
- package/dist/marketplace-install/plugin-install.js +89 -0
- package/dist/marketplace-install/plugin-install.js.map +1 -0
- package/dist/marketplace-install/route-items.d.ts +14 -0
- package/dist/marketplace-install/route-items.d.ts.map +1 -0
- package/dist/marketplace-install/route-items.js +11 -0
- package/dist/marketplace-install/route-items.js.map +1 -0
- package/dist/marketplace-install/use-debounced-value.d.ts +6 -0
- package/dist/marketplace-install/use-debounced-value.d.ts.map +1 -0
- package/dist/marketplace-install/use-debounced-value.js +18 -0
- package/dist/marketplace-install/use-debounced-value.js.map +1 -0
- package/dist/marketplace-install/use-install-action.d.ts +26 -0
- package/dist/marketplace-install/use-install-action.d.ts.map +1 -0
- package/dist/marketplace-install/use-install-action.js +35 -0
- package/dist/marketplace-install/use-install-action.js.map +1 -0
- package/dist/marketplace-install/use-install-preview.d.ts +33 -0
- package/dist/marketplace-install/use-install-preview.d.ts.map +1 -0
- package/dist/marketplace-install/use-install-preview.js +44 -0
- package/dist/marketplace-install/use-install-preview.js.map +1 -0
- package/dist/marketplace-install/use-mount-install.d.ts +80 -0
- package/dist/marketplace-install/use-mount-install.d.ts.map +1 -0
- package/dist/marketplace-install/use-mount-install.js +75 -0
- package/dist/marketplace-install/use-mount-install.js.map +1 -0
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/types.d.ts +23 -7
- package/dist/navigation/types.d.ts.map +1 -1
- package/dist/plugin/registry.d.ts +0 -8
- package/dist/plugin/registry.d.ts.map +1 -1
- package/dist/plugin/registry.js +25 -1
- package/dist/plugin/registry.js.map +1 -1
- package/dist/plugin/types.d.ts +36 -12
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/version.d.ts +6 -4
- package/dist/plugin/version.d.ts.map +1 -1
- package/dist/plugin/version.js +6 -4
- package/dist/plugin/version.js.map +1 -1
- package/dist/query-keys.d.ts +45 -4
- package/dist/query-keys.d.ts.map +1 -1
- package/dist/query-keys.js +52 -4
- package/dist/query-keys.js.map +1 -1
- package/dist/schema-form/json-schema-meta.d.ts +3 -0
- package/dist/schema-form/json-schema-meta.d.ts.map +1 -0
- package/dist/schema-form/json-schema-meta.js +3 -0
- package/dist/schema-form/json-schema-meta.js.map +1 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +2 -0
- package/dist/testing.js.map +1 -1
- package/dist/token-rules.d.ts +26 -0
- package/dist/token-rules.d.ts.map +1 -0
- package/dist/token-rules.js +64 -0
- package/dist/token-rules.js.map +1 -0
- package/package.json +2 -2
- package/src/components/action-menu.tsx +160 -0
- package/src/components/agent-picker.tsx +53 -0
- package/src/components/channel-picker.tsx +68 -0
- package/src/components/components.css +226 -8
- package/src/components/confirm-dialog.tsx +4 -1
- package/src/components/execution-key-picker.tsx +252 -36
- package/src/components/extension-combo-builder.tsx +61 -29
- package/src/components/extension-combo-parts.tsx +28 -38
- package/src/components/extension-config-editor.tsx +307 -0
- package/src/components/extension-grouping.ts +4 -73
- package/src/components/extension-picker.tsx +13 -13
- package/src/components/fleet-report.tsx +38 -4
- package/src/components/holder-kinds.ts +60 -0
- package/src/components/holder-list.tsx +163 -0
- package/src/components/icons/index.ts +0 -2
- package/src/components/icons/nav-map.ts +0 -4
- package/src/components/icons/nav-marks.tsx +0 -15
- package/src/components/named-list-picker.tsx +182 -0
- package/src/components/named-list-test-utils.tsx +47 -0
- package/src/components/recycle-roll.tsx +120 -0
- package/src/components/stepper.tsx +111 -0
- package/src/components/subject-section.tsx +10 -5
- package/src/components/tokens.css +31 -41
- package/src/components/tokens.ts +5 -13
- package/src/components/tool-picker-parts.tsx +17 -6
- package/src/components/tool-picker.tsx +215 -41
- package/src/components/version-history-panel.tsx +8 -0
- package/src/components/version-history-rows.tsx +14 -2
- package/src/errors.ts +10 -0
- package/src/hooks/useCapabilities.ts +59 -10
- package/src/index.ts +54 -14
- package/src/marketplace-install/env-var-fields.tsx +59 -0
- package/src/marketplace-install/index.ts +17 -0
- package/src/marketplace-install/install-env.ts +39 -0
- package/src/marketplace-install/install-mount.ts +96 -0
- package/src/marketplace-install/install-report.tsx +54 -0
- package/src/marketplace-install/install-shell.tsx +99 -0
- package/src/marketplace-install/mount-install.tsx +290 -0
- package/src/marketplace-install/plugin-detail.ts +60 -0
- package/src/marketplace-install/plugin-install.tsx +221 -0
- package/src/marketplace-install/route-items.ts +20 -0
- package/src/marketplace-install/use-debounced-value.ts +18 -0
- package/src/marketplace-install/use-install-action.ts +60 -0
- package/src/marketplace-install/use-install-preview.ts +74 -0
- package/src/marketplace-install/use-mount-install.ts +116 -0
- package/src/navigation/index.ts +1 -0
- package/src/navigation/types.ts +27 -7
- package/src/plugin/registry.ts +19 -1
- package/src/plugin/types.ts +40 -12
- package/src/plugin/version.ts +6 -4
- package/src/query-keys.ts +71 -4
- package/src/schema-form/json-schema-meta.ts +2 -0
- package/src/testing.ts +2 -0
- package/src/token-rules.ts +66 -0
package/README.md
CHANGED
|
@@ -27,8 +27,9 @@ pnpm add @tai42/studio-sdk
|
|
|
27
27
|
- `@tai42/studio-sdk/schema-form` — a form-only `SchemaForm` entry for bundling
|
|
28
28
|
consumers that want the form without the barrel. It imports no CSS by design —
|
|
29
29
|
a subpath consumer loads `tokens.css` and `components.css` explicitly.
|
|
30
|
-
- `@tai42/studio-sdk/testing` — test-only helpers: a registry reset
|
|
31
|
-
`installJsdomStubs()`, which fills the browser APIs jsdom omits
|
|
30
|
+
- `@tai42/studio-sdk/testing` — test-only helpers: a registry reset,
|
|
31
|
+
`installJsdomStubs()`, which fills the browser APIs jsdom omits, and
|
|
32
|
+
`destructiveColorOffences()`, the destructive-emphasis rule below.
|
|
32
33
|
- `@tai42/studio-sdk/tokens.css` — the design-token stylesheet. It also emits the
|
|
33
34
|
canonical `@layer` order, so a host imports it FIRST.
|
|
34
35
|
- `@tai42/studio-sdk/fonts.css` — the self-hosted Inter Variable and Geist Mono
|
|
@@ -107,8 +108,8 @@ than the SDK — it compiles Tailwind v4, whose output needs `@property` and
|
|
|
107
108
|
|
|
108
109
|
`tokens.css` is the styling API: a plugin styles against these names and gets
|
|
109
110
|
whichever half the viewer's theme resolves to. The names are also exported as
|
|
110
|
-
`TOKEN_NAMES` (
|
|
111
|
-
|
|
111
|
+
`TOKEN_NAMES` (79 of them). A new name is not a break; a rename or a removal is a
|
|
112
|
+
breaking change that bumps `STUDIO_PLUGIN_API_VERSION`.
|
|
112
113
|
|
|
113
114
|
The light value is the token; the dark value sits beside it under a
|
|
114
115
|
`--tai-dark-` name that a plugin never reads. Two blocks put the dark half into
|
|
@@ -172,8 +173,8 @@ icons; the `-fill` members are for fills and charts and carry `on-fill` ink.
|
|
|
172
173
|
|
|
173
174
|
| Token | Light | Dark |
|
|
174
175
|
| ----------------------- | ------------------------- | --------------------------- |
|
|
175
|
-
| `--tai-color-ok-text` | `#
|
|
176
|
-
| `--tai-color-err-text` | `#b91c1c` | `#
|
|
176
|
+
| `--tai-color-ok-text` | `#065f46` | `#34d399` |
|
|
177
|
+
| `--tai-color-err-text` | `#b91c1c` | `#fca5a5` |
|
|
177
178
|
| `--tai-color-warn-text` | `#92400e` | `#fbbf24` |
|
|
178
179
|
| `--tai-color-ok-fill` | `#10b981` | `#34d399` |
|
|
179
180
|
| `--tai-color-err-fill` | `#ef4444` | `#f87171` |
|
|
@@ -196,22 +197,18 @@ icons; the `-fill` members are for fills and charts and carry `on-fill` ink.
|
|
|
196
197
|
| `--tai-color-syntax-number` | `var(--tai-color-accent)` | _(same)_ |
|
|
197
198
|
| `--tai-color-syntax-bool` | `var(--tai-color-warn-text)` | _(same)_ |
|
|
198
199
|
|
|
199
|
-
**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
| `--tai-color-
|
|
209
|
-
| `--tai-color-
|
|
210
|
-
| `--tai-color-
|
|
211
|
-
| `--tai-color-danger-hover` | `#7f1d1d` | `#b91c1c` |
|
|
212
|
-
| `--tai-color-danger-surface` | `var(--tai-color-err-tint)` | _(same)_ |
|
|
213
|
-
| `--tai-color-success` | `var(--tai-color-ok-text)` | _(same)_ |
|
|
214
|
-
| `--tai-color-warning` | `var(--tai-color-warn-text)` | _(same)_ |
|
|
200
|
+
**Destructive emphasis.** A fill for the destructive button only, never text:
|
|
201
|
+
error text takes `--tai-color-err-text`. It is a deep red that runs darker than
|
|
202
|
+
the brand accent in both themes, so a destructive control is never mistaken for
|
|
203
|
+
the primary one, with a white label and a hover a shade deeper. A plugin checks its
|
|
204
|
+
own styles against this rule with `destructiveColorOffences()` from
|
|
205
|
+
`@tai42/studio-sdk/testing`.
|
|
206
|
+
|
|
207
|
+
| Token | Light | Dark |
|
|
208
|
+
| ------------------------------- | --------- | --------- |
|
|
209
|
+
| `--tai-color-destructive` | `#991b1b` | `#dc2626` |
|
|
210
|
+
| `--tai-color-destructive-hover` | `#7f1d1d` | `#b91c1c` |
|
|
211
|
+
| `--tai-color-on-destructive` | `#ffffff` | `#ffffff` |
|
|
215
212
|
|
|
216
213
|
**Spacing** (n × 4; there is deliberately no `space-7`). Authored in `rem` so a
|
|
217
214
|
viewer's font-size preference scales them; the px column is the rendered size at
|
|
@@ -262,8 +259,7 @@ preference without reading the media query.
|
|
|
262
259
|
| `--tai-motion-base` | `250ms` |
|
|
263
260
|
|
|
264
261
|
**Elevation.** Only the shadow COLOUR varies by theme; the geometry is written
|
|
265
|
-
once, so a dark override cannot silently move an offset or a blur.
|
|
266
|
-
and `shadow-md` are legacy slots that now alias the lift and overlay geometry.
|
|
262
|
+
once, so a dark override cannot silently move an offset or a blur.
|
|
267
263
|
|
|
268
264
|
| Token | Light | Dark |
|
|
269
265
|
| ---------------------------- | --------------------------------------------- | ------------------- |
|
|
@@ -271,8 +267,6 @@ and `shadow-md` are legacy slots that now alias the lift and overlay geometry.
|
|
|
271
267
|
| `--tai-shadow-overlay-color` | `rgb(0 0 0 / 0.16)` | `rgb(0 0 0 / 0.6)` |
|
|
272
268
|
| `--tai-shadow-lift` | `0 12px 32px var(--tai-shadow-lift-color)` | _(same)_ |
|
|
273
269
|
| `--tai-shadow-overlay` | `0 24px 48px var(--tai-shadow-overlay-color)` | _(same)_ |
|
|
274
|
-
| `--tai-shadow-sm` | `var(--tai-shadow-lift)` | _(same)_ |
|
|
275
|
-
| `--tai-shadow-md` | `var(--tai-shadow-overlay)` | _(same)_ |
|
|
276
270
|
|
|
277
271
|
**Stacking.** `popover` and `tooltip` sit ABOVE the modal layers on purpose: both
|
|
278
272
|
portal to the document body as siblings of a dialog and have to clear its scrim
|
|
@@ -350,6 +344,129 @@ is something the sheet can supply for you:
|
|
|
350
344
|
9. **`--shell-topbar-height` is private to the sheet**, deliberately outside the
|
|
351
345
|
`--tai-*` contract. Do not read it; it is not part of the published API.
|
|
352
346
|
|
|
347
|
+
## Design rules
|
|
348
|
+
|
|
349
|
+
These rules hold for every Studio screen and for a plugin page that wants to sit
|
|
350
|
+
beside them. They name the SDK pieces each case is built from, so a screen reads
|
|
351
|
+
the same way wherever it comes from.
|
|
352
|
+
|
|
353
|
+
**Tokens.** Colour, space, radius, type, motion and elevation come only from the
|
|
354
|
+
names in `TOKEN_NAMES`; a literal colour is never written. Every colour pair is
|
|
355
|
+
checked in both themes, the light `--tai-color-*` and the dark
|
|
356
|
+
`--tai-dark-color-*` values. A status is never told by hue alone: an icon or a word
|
|
357
|
+
sits beside it. The accent is the brand colour only, never a status.
|
|
358
|
+
|
|
359
|
+
**Spacing.** A page is padded by `.tai-page`. Vertical rhythm is `.tai-stack`
|
|
360
|
+
(space-4); inside a group it is `.tai-stack-2`, between groups in a card
|
|
361
|
+
`.tai-stack-3`, and between the sections of a page `.tai-stack-6`. A row of
|
|
362
|
+
controls is `.tai-row`.
|
|
363
|
+
|
|
364
|
+
**Screen patterns.** A new screen uses one of these patterns. A screen with tabs
|
|
365
|
+
under its header (Settings, Dashboard, Marketplace, the Conversations landing)
|
|
366
|
+
takes a pattern per tab.
|
|
367
|
+
|
|
368
|
+
- **Browse and inspect.** A split list and detail (`.tai-split`), with the
|
|
369
|
+
selection held in the URL search. Tools, whose list pane is an `ExplorerView`;
|
|
370
|
+
Presets; States; Storage; a Conversations route, its threads beside the open
|
|
371
|
+
transcript.
|
|
372
|
+
- **Catalog.** A directory of cards with search and filters. Connectors and the
|
|
373
|
+
Tools card view, through `ExplorerView`; the Marketplace Browse tab, a card grid
|
|
374
|
+
with facet filters and Load more.
|
|
375
|
+
- **Registry.** Tables or lists of records in cards. Create and the row actions
|
|
376
|
+
open a dialog built on `Dialog` (`FormDialog` or the screen's own); edit opens
|
|
377
|
+
one too or happens in place; a destructive action is confirmed before it runs.
|
|
378
|
+
Scheduling, Members, the Conversations routes and per-target configs, the
|
|
379
|
+
Marketplace Installed tab, and the Profiles, API keys and Roles tabs of
|
|
380
|
+
Settings.
|
|
381
|
+
- **Registry with inline create.** The records list first, then the create forms
|
|
382
|
+
in cards on the page below them; edit, where a record has one, in a `Dialog`; a
|
|
383
|
+
destructive action confirmed before it runs. Hooks, Served endpoints.
|
|
384
|
+
- **Replaced detail.** A search param swaps the page or the tab for one item. The
|
|
385
|
+
Marketplace plugin page, a trace in the Dashboard Tracing tab, a state template
|
|
386
|
+
or a state's records.
|
|
387
|
+
- **Run surface.** A list, then the run view in its place. Agents.
|
|
388
|
+
- **Inbox.** Newest-first cards, the rest paged in by a button at the foot: Load
|
|
389
|
+
more where the server pages (Interactions), Show more where the whole feed is
|
|
390
|
+
already loaded (Notifications).
|
|
391
|
+
- **Status and configuration.** Stacked cards of read-only views and in-place
|
|
392
|
+
editors, no create dialog; a destructive or fleet-wide action is confirmed in a
|
|
393
|
+
`ConfirmDialog`. Manifest, System, the Dashboard tab of Dashboard, the Settings,
|
|
394
|
+
Environment and Backup tabs of Settings, and the Failed deliveries tab of the
|
|
395
|
+
Conversations landing (one read-only card that re-reads itself).
|
|
396
|
+
|
|
397
|
+
A multi-step create is a `Stepper` inside a `Dialog`.
|
|
398
|
+
|
|
399
|
+
**States.** A page or a region (a card, a pane, a tab) shows one state at a time,
|
|
400
|
+
each drawn by its SDK piece:
|
|
401
|
+
|
|
402
|
+
- loading: a `Skeleton` in the shape of the content, or a labelled `Spinner` where
|
|
403
|
+
the content has no fixed shape;
|
|
404
|
+
- empty: an `EmptyState` whose title says what is missing and whose `action`
|
|
405
|
+
gives the next step;
|
|
406
|
+
- off, when the server answers that the feature is not configured:
|
|
407
|
+
`FeatureDisabled`;
|
|
408
|
+
- no grant: as below;
|
|
409
|
+
- failed: an `ErrorState`, with `onRetry` when a retry can succeed;
|
|
410
|
+
- then the content.
|
|
411
|
+
|
|
412
|
+
Content already drawn stays when a later read fails (the next page, a secondary
|
|
413
|
+
read): the failure is shown beside it, as an `ErrorState` or a muted line saying
|
|
414
|
+
what could not be read and why. A control inside a form follows the picker rules
|
|
415
|
+
instead.
|
|
416
|
+
|
|
417
|
+
**No grant.** What the caller's access does not reach is not drawn. A write
|
|
418
|
+
control is hidden through `useCanWrite`, never shown disabled, and in its place,
|
|
419
|
+
where the reader would look for it, a muted `role="status"` line says what is out
|
|
420
|
+
of reach and, where the screen knows it, the access it needs ("Running this tool
|
|
421
|
+
is outside your access — it is shown read-only."). A whole region the caller
|
|
422
|
+
cannot read is an `EmptyState` whose title says it is not available and whose
|
|
423
|
+
description says what it would show and the access it needs. A no-grant state
|
|
424
|
+
has no Retry and never wears the error ground: a refusal is an answer, not a
|
|
425
|
+
failure. Readable content stays, read-only. A secondary control (a row's Delete)
|
|
426
|
+
is hidden without a line. A screen the caller cannot reach leaves the sidebar;
|
|
427
|
+
its URL still renders, and a refusal the screen did not expect is an
|
|
428
|
+
`ErrorState`.
|
|
429
|
+
|
|
430
|
+
**Disabled controls and results.** A control disabled for a reason the screen
|
|
431
|
+
does not otherwise show says the reason in text beside it. There is no toast: a
|
|
432
|
+
result is shown inline next to the control that caused it, a `role="status"` line
|
|
433
|
+
for an outcome and `role="alert"` (or an `ErrorState`) for a failure.
|
|
434
|
+
|
|
435
|
+
**Pickers.** A picker is an SDK component wrapped in `Field` with a visible
|
|
436
|
+
label. It reads a structural query interface
|
|
437
|
+
(`{ data, isPending, isError, isSuccess, error, refetch }`, the shape
|
|
438
|
+
`ExecutionKeyPicker` takes) and names no query library. Pending is the control
|
|
439
|
+
disabled with the placeholder "Loading <plural noun>…"; error is an `ErrorState`
|
|
440
|
+
with retry inside the field (`group` set); empty is a muted `role="status"` line
|
|
441
|
+
naming where to create one; no grant to read the list is the no-grant line in
|
|
442
|
+
place of the control. Values render as text, never HTML. A picker is composed
|
|
443
|
+
outside `SchemaForm`. Two cases differ:
|
|
444
|
+
|
|
445
|
+
- A picker that is one control of a larger group on its host (a `fieldset` whose
|
|
446
|
+
`legend` names the group) takes no label of its own: its control carries an
|
|
447
|
+
`aria-label` that names it within the group (the legend, then what the control
|
|
448
|
+
picks), and its states render in the same place without a `Field`.
|
|
449
|
+
- When the read behind the list fails and the same failure is already shown once,
|
|
450
|
+
with retry, elsewhere on the same surface, the picker draws no second
|
|
451
|
+
`ErrorState`: in place of the control it shows a muted `role="status"` line
|
|
452
|
+
saying the list could not be read and where that error is shown, with no retry.
|
|
453
|
+
A surface shows one failure with retry once.
|
|
454
|
+
|
|
455
|
+
**Stepper.** An ordered list in a labelled `nav`, with `aria-current="step"` on
|
|
456
|
+
the current step and each step's status spoken in visually hidden text. Done,
|
|
457
|
+
current, upcoming and error are told apart by marker shape and icon as well as
|
|
458
|
+
colour, filled with the ok and err tokens (never the accent, never a destructive
|
|
459
|
+
token). Tab and Enter or Space reach only the steps that can be revisited. Below
|
|
460
|
+
the narrow breakpoint (640 px) the list collapses to "Step n of m: <label>".
|
|
461
|
+
Motion follows the reduced-motion rule, and targets are 44 px on coarse pointers.
|
|
462
|
+
|
|
463
|
+
**Keyboard and accessibility.** There are no global shortcuts. Every interactive
|
|
464
|
+
element is reachable by Tab in reading order; Enter and Space work on custom rows;
|
|
465
|
+
the focus-visible ring comes from the five-state contract. A route change moves
|
|
466
|
+
focus to the page `<h1>`; dialogs trap focus and return it. The bar is WCAG
|
|
467
|
+
2.0/2.1 A and AA in both themes, enforced by an axe audit over every route and by
|
|
468
|
+
the SDK's guard tests.
|
|
469
|
+
|
|
353
470
|
## Usage
|
|
354
471
|
|
|
355
472
|
```ts
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ActionMenu` — a row's or a card's overflow menu: a ghost "Actions" button
|
|
3
|
+
* whose accessible name the caller completes ("Actions for <name>", which keeps
|
|
4
|
+
* the visible word at its start) that opens a `role="menu"` list of
|
|
5
|
+
* `role="menuitem"` buttons, the WAI-ARIA menu-button pattern.
|
|
6
|
+
*
|
|
7
|
+
* Opening moves focus to the first item; ArrowDown/ArrowUp move between items
|
|
8
|
+
* (wrapping), Home/End jump to the ends, Escape closes and returns focus to the
|
|
9
|
+
* trigger, Tab closes. Activating an item closes the menu, returns focus to the
|
|
10
|
+
* trigger, then runs the item's action, so a dialog the action opens takes focus
|
|
11
|
+
* from a settled trigger. A pointer press outside the menu closes it.
|
|
12
|
+
*
|
|
13
|
+
* The caller passes only the items the session may use; with none the menu is
|
|
14
|
+
* not drawn at all (a hidden control takes no line).
|
|
15
|
+
*/
|
|
16
|
+
import { type ReactNode } from 'react';
|
|
17
|
+
export interface ActionMenuItem {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly label: string;
|
|
20
|
+
readonly onSelect: () => void;
|
|
21
|
+
/** Paints the item in the error tone (a destructive action). */
|
|
22
|
+
readonly danger?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface ActionMenuProps {
|
|
25
|
+
/** The trigger's accessible name, e.g. "Actions for Acme". */
|
|
26
|
+
readonly label: string;
|
|
27
|
+
readonly items: readonly ActionMenuItem[];
|
|
28
|
+
}
|
|
29
|
+
export declare function ActionMenu({ label, items }: ActionMenuProps): ReactNode;
|
|
30
|
+
//# sourceMappingURL=action-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-menu.d.ts","sourceRoot":"","sources":["../../src/components/action-menu.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAsB,KAAK,SAAS,EAAsC,MAAM,OAAO,CAAC;AAI/F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;CAC3C;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,eAAe,GAAG,SAAS,CA8HvE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `ActionMenu` — a row's or a card's overflow menu: a ghost "Actions" button
|
|
4
|
+
* whose accessible name the caller completes ("Actions for <name>", which keeps
|
|
5
|
+
* the visible word at its start) that opens a `role="menu"` list of
|
|
6
|
+
* `role="menuitem"` buttons, the WAI-ARIA menu-button pattern.
|
|
7
|
+
*
|
|
8
|
+
* Opening moves focus to the first item; ArrowDown/ArrowUp move between items
|
|
9
|
+
* (wrapping), Home/End jump to the ends, Escape closes and returns focus to the
|
|
10
|
+
* trigger, Tab closes. Activating an item closes the menu, returns focus to the
|
|
11
|
+
* trigger, then runs the item's action, so a dialog the action opens takes focus
|
|
12
|
+
* from a settled trigger. A pointer press outside the menu closes it.
|
|
13
|
+
*
|
|
14
|
+
* The caller passes only the items the session may use; with none the menu is
|
|
15
|
+
* not drawn at all (a hidden control takes no line).
|
|
16
|
+
*/
|
|
17
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
18
|
+
import { ChevronDownIcon } from './icons';
|
|
19
|
+
export function ActionMenu({ label, items }) {
|
|
20
|
+
const [open, setOpen] = useState(false);
|
|
21
|
+
const menuId = useId();
|
|
22
|
+
const triggerRef = useRef(null);
|
|
23
|
+
const menuRef = useRef(null);
|
|
24
|
+
const itemRefs = useRef([]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!open)
|
|
27
|
+
return undefined;
|
|
28
|
+
itemRefs.current[0]?.focus();
|
|
29
|
+
const onPointerDown = (event) => {
|
|
30
|
+
const target = event.target;
|
|
31
|
+
if (target === null)
|
|
32
|
+
return;
|
|
33
|
+
if (menuRef.current?.contains(target) === true)
|
|
34
|
+
return;
|
|
35
|
+
if (triggerRef.current?.contains(target) === true)
|
|
36
|
+
return;
|
|
37
|
+
setOpen(false);
|
|
38
|
+
};
|
|
39
|
+
document.addEventListener('pointerdown', onPointerDown);
|
|
40
|
+
return () => {
|
|
41
|
+
document.removeEventListener('pointerdown', onPointerDown);
|
|
42
|
+
};
|
|
43
|
+
}, [open]);
|
|
44
|
+
if (items.length === 0)
|
|
45
|
+
return null;
|
|
46
|
+
const close = () => {
|
|
47
|
+
setOpen(false);
|
|
48
|
+
triggerRef.current?.focus();
|
|
49
|
+
};
|
|
50
|
+
const focusItem = (index) => {
|
|
51
|
+
const count = items.length;
|
|
52
|
+
itemRefs.current[((index % count) + count) % count]?.focus();
|
|
53
|
+
};
|
|
54
|
+
const onMenuKeyDown = (event) => {
|
|
55
|
+
const current = itemRefs.current.findIndex((item) => item === document.activeElement);
|
|
56
|
+
switch (event.key) {
|
|
57
|
+
case 'ArrowDown':
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
focusItem(current + 1);
|
|
60
|
+
break;
|
|
61
|
+
case 'ArrowUp':
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
focusItem(current - 1);
|
|
64
|
+
break;
|
|
65
|
+
case 'Home':
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
focusItem(0);
|
|
68
|
+
break;
|
|
69
|
+
case 'End':
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
focusItem(items.length - 1);
|
|
72
|
+
break;
|
|
73
|
+
case 'Escape':
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
event.stopPropagation();
|
|
76
|
+
close();
|
|
77
|
+
break;
|
|
78
|
+
case 'Tab':
|
|
79
|
+
setOpen(false);
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return (_jsxs("div", { className: "tai-action-menu", children: [_jsxs("button", { ref: triggerRef, type: "button", className: "tai-btn tai-btn-ghost", "aria-label": label, "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? menuId : undefined, onClick: () => {
|
|
86
|
+
setOpen((was) => !was);
|
|
87
|
+
}, onKeyDown: (event) => {
|
|
88
|
+
if (event.key === 'ArrowDown' && !open) {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
setOpen(true);
|
|
91
|
+
}
|
|
92
|
+
}, children: ["Actions", _jsx(ChevronDownIcon, {})] }), open ? (_jsx("div", { ref: menuRef, id: menuId, role: "menu", tabIndex: -1, "aria-label": label, className: "tai-action-menu-list", onKeyDown: onMenuKeyDown, children: items.map((item, index) => (_jsx("button", { ref: (node) => {
|
|
93
|
+
itemRefs.current[index] = node;
|
|
94
|
+
}, type: "button", role: "menuitem", tabIndex: -1, className: item.danger === true
|
|
95
|
+
? 'tai-action-menu-item tai-action-menu-item-danger'
|
|
96
|
+
: 'tai-action-menu-item', onClick: () => {
|
|
97
|
+
close();
|
|
98
|
+
item.onSelect();
|
|
99
|
+
}, children: item.label }, item.id))) })) : null] }));
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=action-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-menu.js","sourceRoot":"","sources":["../../src/components/action-menu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `AgentPicker` — picks a registered agent by name from the agent list read
|
|
3
|
+
* (`GET /api/agents`) the host owns and hands in. Presentational: it fetches nothing
|
|
4
|
+
* and names no query library. It draws the read's states and its own copy, and flags
|
|
5
|
+
* a stored agent the loaded list does not hold as "not registered".
|
|
6
|
+
*/
|
|
7
|
+
import type { AgentListing } from '@tai42/api-client';
|
|
8
|
+
import type { ReactNode } from 'react';
|
|
9
|
+
import { type ListReadFlags } from './named-list-picker';
|
|
10
|
+
/** The subset of the agent list read this picker reads; a TanStack query result satisfies it. */
|
|
11
|
+
export interface AgentListQuery extends ListReadFlags {
|
|
12
|
+
readonly data: AgentListing | undefined;
|
|
13
|
+
}
|
|
14
|
+
export interface AgentPickerProps {
|
|
15
|
+
readonly query: AgentListQuery;
|
|
16
|
+
readonly value: string;
|
|
17
|
+
readonly onValueChange: (value: string) => void;
|
|
18
|
+
/** The host form's field error, shown under the control while a `Select` renders. */
|
|
19
|
+
readonly error?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
export declare function AgentPicker({ query, value, onValueChange, error }: AgentPickerProps): ReactNode;
|
|
22
|
+
//# sourceMappingURL=agent-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-picker.d.ts","sourceRoot":"","sources":["../../src/components/agent-picker.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,KAAK,aAAa,EAAuC,MAAM,qBAAqB,CAAC;AAE9F,iGAAiG;AACjG,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAiBD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,SAAS,CAY/F"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AppLink } from '../navigation/app-link';
|
|
3
|
+
import { NamedListPicker } from './named-list-picker';
|
|
4
|
+
const COPY = {
|
|
5
|
+
label: 'Agent',
|
|
6
|
+
loadingPlaceholder: 'Loading agents…',
|
|
7
|
+
placeholder: 'Select an agent',
|
|
8
|
+
forbiddenNote: 'This session cannot list agents. Picking one needs read access to GET /api/agents; ask an administrator to grant it.',
|
|
9
|
+
emptyNote: 'No agents are registered on this deployment.',
|
|
10
|
+
emptyAction: (_jsx(AppLink, { to: "agents", className: "tai-link", children: "Open the Agents screen" })),
|
|
11
|
+
unlistedLabel: 'not registered',
|
|
12
|
+
};
|
|
13
|
+
export function AgentPicker({ query, value, onValueChange, error }) {
|
|
14
|
+
const names = (query.data?.items ?? []).map((item) => item.name);
|
|
15
|
+
return (_jsx(NamedListPicker, { query: query, names: names, value: value, onValueChange: onValueChange, error: error, copy: COPY }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=agent-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-picker.js","sourceRoot":"","sources":["../../src/components/agent-picker.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAA0C,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAe9F,MAAM,IAAI,GAAkB;IAC1B,KAAK,EAAE,OAAO;IACd,kBAAkB,EAAE,iBAAiB;IACrC,WAAW,EAAE,iBAAiB;IAC9B,aAAa,EACX,sHAAsH;IACxH,SAAS,EAAE,8CAA8C;IACzD,WAAW,EAAE,CACX,KAAC,OAAO,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAC,UAAU,uCAE/B,CACX;IACD,aAAa,EAAE,gBAAgB;CAChC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAoB;IAClF,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,GACV,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ChannelPicker` — picks an installed channel plugin by name from the channel list
|
|
3
|
+
* read (`GET /api/channels`) the host owns and hands in. Presentational: it fetches
|
|
4
|
+
* nothing and names no query library. It draws the read's states and its own copy,
|
|
5
|
+
* and flags a stored channel the loaded list does not hold as "not installed".
|
|
6
|
+
*/
|
|
7
|
+
import type { Channels } from '@tai42/api-client';
|
|
8
|
+
import type { ReactNode } from 'react';
|
|
9
|
+
import { type ListReadFlags } from './named-list-picker';
|
|
10
|
+
/** The subset of the channel list read this picker reads; a TanStack query result satisfies it. */
|
|
11
|
+
export interface ChannelListQuery extends ListReadFlags {
|
|
12
|
+
readonly data: Channels | undefined;
|
|
13
|
+
}
|
|
14
|
+
export interface ChannelPickerProps {
|
|
15
|
+
readonly query: ChannelListQuery;
|
|
16
|
+
readonly value: string;
|
|
17
|
+
readonly onValueChange: (value: string) => void;
|
|
18
|
+
/** The host form's field error, shown under the control while a `Select` renders. */
|
|
19
|
+
readonly error?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The named channel's declared hint for a route's identity: the hint, `null` for a
|
|
23
|
+
* listed channel that declares none, `undefined` when the name is not listed.
|
|
24
|
+
*/
|
|
25
|
+
export declare function channelIdentityHint(data: Channels, name: string): string | null | undefined;
|
|
26
|
+
export declare function ChannelPicker({ query, value, onValueChange, error, }: ChannelPickerProps): ReactNode;
|
|
27
|
+
//# sourceMappingURL=channel-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-picker.d.ts","sourceRoot":"","sources":["../../src/components/channel-picker.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,KAAK,aAAa,EAAuC,MAAM,qBAAqB,CAAC;AAE9F,mGAAmG;AACnG,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAG3F;AAkBD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,aAAa,EACb,KAAK,GACN,EAAE,kBAAkB,GAAG,SAAS,CAYhC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AppLink } from '../navigation/app-link';
|
|
3
|
+
import { NamedListPicker } from './named-list-picker';
|
|
4
|
+
/**
|
|
5
|
+
* The named channel's declared hint for a route's identity: the hint, `null` for a
|
|
6
|
+
* listed channel that declares none, `undefined` when the name is not listed.
|
|
7
|
+
*/
|
|
8
|
+
export function channelIdentityHint(data, name) {
|
|
9
|
+
const entry = data.channels.find((channel) => channel.name === name);
|
|
10
|
+
return entry === undefined ? undefined : entry.identity_hint;
|
|
11
|
+
}
|
|
12
|
+
const COPY = {
|
|
13
|
+
label: 'Channel',
|
|
14
|
+
description: 'An installed channel plugin; the answer goes back on the same channel.',
|
|
15
|
+
loadingPlaceholder: 'Loading channels…',
|
|
16
|
+
placeholder: 'Select a channel',
|
|
17
|
+
forbiddenNote: 'This session cannot list channels. Picking one needs read access to GET /api/channels; ask an administrator to grant it.',
|
|
18
|
+
emptyNote: 'No channels are installed on this deployment.',
|
|
19
|
+
emptyAction: (_jsx(AppLink, { to: "marketplace", search: { kind: 'channel' }, className: "tai-link", children: "Browse channel plugins" })),
|
|
20
|
+
unlistedLabel: 'not installed',
|
|
21
|
+
};
|
|
22
|
+
export function ChannelPicker({ query, value, onValueChange, error, }) {
|
|
23
|
+
const names = (query.data?.channels ?? []).map((channel) => channel.name);
|
|
24
|
+
return (_jsx(NamedListPicker, { query: query, names: names, value: value, onValueChange: onValueChange, error: error, copy: COPY }));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=channel-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-picker.js","sourceRoot":"","sources":["../../src/components/channel-picker.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAA0C,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAe9F;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAc,EAAE,IAAY;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACrE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;AAC/D,CAAC;AAED,MAAM,IAAI,GAAkB;IAC1B,KAAK,EAAE,SAAS;IAChB,WAAW,EAAE,wEAAwE;IACrF,kBAAkB,EAAE,mBAAmB;IACvC,WAAW,EAAE,kBAAkB;IAC/B,aAAa,EACX,0HAA0H;IAC5H,SAAS,EAAE,+CAA+C;IAC1D,WAAW,EAAE,CACX,KAAC,OAAO,IAAC,EAAE,EAAC,aAAa,EAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,EAAC,UAAU,uCAEjE,CACX;IACD,aAAa,EAAE,eAAe;CAC/B,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,aAAa,EACb,KAAK,GACc;IACnB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,GACV,CACH,CAAC;AACJ,CAAC"}
|