@aquera/mcp-ui-render 0.0.1

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +437 -0
  2. package/CONFIGURATION.md +178 -0
  3. package/LICENSE +21 -0
  4. package/README.md +237 -0
  5. package/RELEASE-NOTES.md +77 -0
  6. package/TEST-PLAN.md +72 -0
  7. package/USAGE.md +100 -0
  8. package/package.json +52 -0
  9. package/src/controls.d.ts +1 -0
  10. package/src/controls.js +572 -0
  11. package/src/controls.js.map +1 -0
  12. package/src/elements/aq-mcp-config.d.ts +289 -0
  13. package/src/elements/aq-mcp-config.js +673 -0
  14. package/src/elements/aq-mcp-config.js.map +1 -0
  15. package/src/elements/aq-mcp-field.d.ts +92 -0
  16. package/src/elements/aq-mcp-field.js +275 -0
  17. package/src/elements/aq-mcp-field.js.map +1 -0
  18. package/src/elements/aq-mcp-section.d.ts +101 -0
  19. package/src/elements/aq-mcp-section.js +261 -0
  20. package/src/elements/aq-mcp-section.js.map +1 -0
  21. package/src/engine/status.d.ts +31 -0
  22. package/src/engine/status.js +44 -0
  23. package/src/engine/status.js.map +1 -0
  24. package/src/engine/submit.d.ts +26 -0
  25. package/src/engine/submit.js +37 -0
  26. package/src/engine/submit.js.map +1 -0
  27. package/src/engine/validate.d.ts +24 -0
  28. package/src/engine/validate.js +144 -0
  29. package/src/engine/validate.js.map +1 -0
  30. package/src/engine/values.d.ts +20 -0
  31. package/src/engine/values.js +42 -0
  32. package/src/engine/values.js.map +1 -0
  33. package/src/index.d.ts +18 -0
  34. package/src/index.js +20 -0
  35. package/src/index.js.map +1 -0
  36. package/src/mcp-ui-render.css +811 -0
  37. package/src/registry.d.ts +63 -0
  38. package/src/registry.js +39 -0
  39. package/src/registry.js.map +1 -0
  40. package/src/types.d.ts +239 -0
  41. package/src/types.js +8 -0
  42. package/src/types.js.map +1 -0
@@ -0,0 +1,572 @@
1
+ /**
2
+ * Default control renderers — the `ui-component`s the library ships out of the
3
+ * box (the six from the bootstrap contract §5, plus `radio`, `file`,
4
+ * `test-connection-report`, and `properties-table`), each mapped to a Nile
5
+ * element (or, for `properties-table`, a plain semantic `<table>` — no
6
+ * dedicated Nile table component is used here, see its own doc comment). In the
7
+ * sectioned-form layout the label + help render VISIBLY in the field's left
8
+ * column (see `<aq-mcp-field>`), so `input`/`textarea`/`password`/`select`/
9
+ * `radio` also pass that same text into Nile's own `label` property — each of
10
+ * those controls only wires its native `for`/`aria-labelledby` accessible-name
11
+ * association when `label` is set (confirmed by reading their shadow-DOM
12
+ * templates: an empty `label` renders the association `aria-hidden`, i.e. no
13
+ * accessible name at all, otherwise). Nile's own internal label element is
14
+ * then visually hidden (`::part()`, mcp-ui-render.css) so nothing appears
15
+ * twice on screen — it exists purely to give the control a real accessible
16
+ * name. `checkbox` (`nile-slide-toggle`) has no equivalent wiring in Nile
17
+ * itself for its internal checkbox — its own `label`/`sublabel` render as
18
+ * plain sibling text, never `for`/`aria-labelledby`-associated with the
19
+ * `<input>` — a gap in Nile, not fixable from here; flagged, not silently
20
+ * worked around. Controls otherwise keep value/required/error/disabled.
21
+ * Registered into the component registry; a host can override or add
22
+ * controls (§9.1). An unknown `ui-component` never reaches here — the field
23
+ * engine falls back to the datatype's default control.
24
+ */
25
+ import { html } from 'lit';
26
+ import { registerControl } from './registry.js';
27
+ function labelOf(field) {
28
+ return field.label ?? field.attribute;
29
+ }
30
+ function detailValue(e) {
31
+ return e.detail?.value;
32
+ }
33
+ function detailChecked(e) {
34
+ return !!e.detail?.checked;
35
+ }
36
+ function isLabeledOption(o) {
37
+ return o !== null && typeof o === 'object' && 'value' in o;
38
+ }
39
+ /** The value submitted/emitted for an option — always the raw code, never the label. */
40
+ function optionValue(o) {
41
+ return String(isLabeledOption(o) ? o.value : o);
42
+ }
43
+ /** The text shown to the user — the `label` when given, else the value itself (unchanged
44
+ * behavior for plain-primitive options, so this is purely additive). */
45
+ function optionLabel(o) {
46
+ return isLabeledOption(o) ? o.label : String(o);
47
+ }
48
+ /** `select`/`radio` shared: the effective option list — a host-fed `dynamicOptions` entry
49
+ * (§9.6) takes priority over the descriptor's own static `field.options`, so a host that has
50
+ * since resolved a `tool`-backed list doesn't need to also blank out the original descriptor.
51
+ * `pending` distinguishes "empty because a `tool` fetch hasn't answered yet" (expected,
52
+ * temporary, no warning) from a genuine §15 descriptor defect (a plain field with no options
53
+ * and no way to ever get any) — both render disabled, only the latter warns. */
54
+ function resolveOptions(field, dynamicOptions) {
55
+ const options = (dynamicOptions?.[field.attribute] ?? field.options ?? []);
56
+ return { options, pending: options.length === 0 && !!field.tool };
57
+ }
58
+ /** `datatype: "object"` has no dedicated editor control (§4/§8 declare the datatype and its
59
+ * validation shape — `requiredKeys` + per-value regex — but no `ui-component` of its own).
60
+ * `input`/`textarea` are the two controls a descriptor might reasonably pair it with; both
61
+ * render it as editable JSON text. Display: a `value` that's already a plain object/array
62
+ * (the seeded/valid-JSON state) is pretty-printed; a `value` that's a STRING (set by
63
+ * `objectInputHandler` below while the user is mid-typing invalid/incomplete JSON) is shown
64
+ * verbatim — re-stringifying it would wrap it in escaped quotes and corrupt what they typed. */
65
+ function displayValue(field, value) {
66
+ if (field.datatype !== 'object')
67
+ return value == null ? '' : String(value);
68
+ if (value == null)
69
+ return '';
70
+ return typeof value === 'string' ? value : JSON.stringify(value, null, 2);
71
+ }
72
+ /** `datatype: "object"` input handler shared by `input`/`textarea`: parse the typed text as
73
+ * JSON and emit the real object once it's valid; while it's still invalid/incomplete (normal
74
+ * mid-keystroke for anything beyond a bare `{}`), emit the raw string instead of blocking the
75
+ * keystroke — `validateField`'s object branch already treats a non-object value as an empty
76
+ * object rather than crashing (§8), so this degrades to an ordinary "required key(s) missing"
77
+ * validation message, never a throw, until the JSON becomes valid again. */
78
+ function objectInputHandler(onInput) {
79
+ return (e) => {
80
+ const raw = detailValue(e);
81
+ try {
82
+ onInput(JSON.parse(String(raw)));
83
+ }
84
+ catch {
85
+ onInput(raw);
86
+ }
87
+ };
88
+ }
89
+ /**
90
+ * The placeholder for a text-like control: the field's own `defaultValue` and
91
+ * nothing else. An interim version substituted "Not set" for an empty field in
92
+ * the dense layout — invented copy standing in for a value the descriptor
93
+ * never supplied. An empty field now simply renders empty.
94
+ */
95
+ function placeholderFor(field) {
96
+ return field.defaultValue != null ? String(field.defaultValue) : '';
97
+ }
98
+ /**
99
+ * A quiet confirmation that a field the user filled in actually passes its
100
+ * `validation` rules — slotted into `nile-input`'s own `suffix`. A glyph, not
101
+ * a word, so it asserts nothing the descriptor did not.
102
+ *
103
+ * Only in the dense/accordion layout, and only for a field that has BOTH a
104
+ * value and a rule to satisfy: a mark on a field with no `validation` regex
105
+ * confirms nothing (any text would earn it), and one on an untouched field
106
+ * would read as approval of emptiness.
107
+ */
108
+ function validMark(field, value, error, dense) {
109
+ if (!dense || error)
110
+ return '';
111
+ if (!field.validation?.length)
112
+ return '';
113
+ if (value === null || value === undefined || String(value).trim() === '')
114
+ return '';
115
+ return html `<nile-glyph
116
+ slot="suffix"
117
+ class="aq-mcp-field__valid"
118
+ name="ng-check"
119
+ method="stroke"
120
+ size="16"
121
+ color="currentColor"
122
+ ></nile-glyph>`;
123
+ }
124
+ /** `input` — single-line text (default for string/number). */
125
+ registerControl('input', ({ field, value, error, onInput, dense }) => {
126
+ const isNumber = field.datatype === 'number';
127
+ const isObject = field.datatype === 'object';
128
+ const handleInput = isObject ? objectInputHandler(onInput) : (e) => onInput(detailValue(e));
129
+ return html `<nile-input
130
+ type=${isNumber ? 'number' : 'text'}
131
+ placeholder=${placeholderFor(field)}
132
+ .value=${displayValue(field, value)}
133
+ .label=${labelOf(field)}
134
+ ?required=${!!field.isRequired}
135
+ ?readonly=${!!field.readOnly}
136
+ ?disabled=${!!field.readOnly}
137
+ .error=${!!error}
138
+ .errorMessage=${error ?? ''}
139
+ @nile-input=${handleInput}
140
+ @nile-change=${handleInput}
141
+ >
142
+ ${validMark(field, value, error, dense)}
143
+ </nile-input>`;
144
+ });
145
+ /** `textarea` — multi-line text; the recommended pairing for `datatype: "object"` (JSON needs
146
+ * more than one line to be legible) — see `displayValue`/`objectInputHandler` above. */
147
+ registerControl('textarea', ({ field, value, error, onInput }) => {
148
+ const isObject = field.datatype === 'object';
149
+ const handleInput = isObject ? objectInputHandler(onInput) : (e) => onInput(detailValue(e));
150
+ return html `<nile-textarea
151
+ placeholder=${placeholderFor(field)}
152
+ .value=${displayValue(field, value)}
153
+ .label=${labelOf(field)}
154
+ ?required=${!!field.isRequired}
155
+ ?readonly=${!!field.readOnly}
156
+ .error=${!!error}
157
+ .errorMessage=${error ?? ''}
158
+ @nile-input=${handleInput}
159
+ @nile-change=${handleInput}
160
+ ></nile-textarea>`;
161
+ });
162
+ /** `password` — masked entry; implies secret. A `writeOnce` field's ALREADY-stored
163
+ * value never reaches here — that renders as the separate masked+Replace view
164
+ * in `<aq-mcp-field>` (`isSetWriteOnce()`); this control only renders for a
165
+ * genuinely blank field or while actively typing a replacement, so it must
166
+ * reflect `value` like every other control — hardcoding it to '' fought the
167
+ * live-validation re-render on every keystroke, resetting whatever was typed. */
168
+ registerControl('password', ({ field, value, error, onInput }) => {
169
+ return html `<nile-input
170
+ type="password"
171
+ password-toggle
172
+ placeholder=${field.writeOnce ? 'Enter a new value' : ''}
173
+ .value=${value == null ? '' : String(value)}
174
+ .label=${labelOf(field)}
175
+ ?required=${!!field.isRequired}
176
+ .error=${!!error}
177
+ .errorMessage=${error ?? ''}
178
+ @nile-input=${(e) => onInput(detailValue(e))}
179
+ @nile-change=${(e) => onInput(detailValue(e))}
180
+ ></nile-input>`;
181
+ });
182
+ /** `select` — one value (or several when datatype is array). Every select needs `options`
183
+ * (§15) — either declared statically, or resolved dynamically via `field.tool` + a host-fed
184
+ * `dynamicOptions` entry (§9.6). */
185
+ registerControl('select', ({ field, value, error, onInput, dynamicOptions }) => {
186
+ const multiple = field.datatype === 'array';
187
+ const { options, pending } = resolveOptions(field, dynamicOptions);
188
+ if (options.length === 0 && !pending) {
189
+ // eslint-disable-next-line no-console
190
+ console.warn(`[mcp-ui-render] select "${field.attribute}" has no options: descriptor defect (§15).`);
191
+ }
192
+ return html `<nile-select
193
+ ?multiple=${multiple}
194
+ .label=${labelOf(field)}
195
+ ?required=${!!field.isRequired}
196
+ ?disabled=${!!field.readOnly || options.length === 0}
197
+ .value=${value ?? (multiple ? [] : '')}
198
+ .error=${!!error}
199
+ .errorMessage=${error ?? ''}
200
+ @nile-change=${(e) => onInput(detailValue(e))}
201
+ >
202
+ ${options.map((o) => html `<nile-option value=${optionValue(o)}>${optionLabel(o)}</nile-option>`)}
203
+ </nile-select>`;
204
+ });
205
+ /** `radio` — one value from a small, fixed option set. Same §9.6/§15 rules as `select`:
206
+ * `options` may be static or resolved dynamically via `field.tool` + `dynamicOptions`. */
207
+ registerControl('radio', ({ field, value, error, onInput, dynamicOptions }) => {
208
+ const { options, pending } = resolveOptions(field, dynamicOptions);
209
+ if (options.length === 0 && !pending) {
210
+ // eslint-disable-next-line no-console
211
+ console.warn(`[mcp-ui-render] radio "${field.attribute}" has no options: descriptor defect (§15).`);
212
+ }
213
+ return html `<nile-radio-group
214
+ .label=${labelOf(field)}
215
+ .value=${value == null ? '' : String(value)}
216
+ ?required=${!!field.isRequired}
217
+ ?disabled=${!!field.readOnly || options.length === 0}
218
+ .errorMessage=${error ?? ''}
219
+ @nile-change=${(e) => onInput(detailValue(e))}
220
+ >
221
+ ${options.map((o) => html `<nile-radio value=${optionValue(o)}>${optionLabel(o)}</nile-radio>`)}
222
+ </nile-radio-group>`;
223
+ });
224
+ /** `checkbox` — boolean (validation is ignored for booleans, §8). */
225
+ registerControl('checkbox', ({ field, value, onInput }) => {
226
+ const checked = value === true || value === 'true';
227
+ return html `<nile-slide-toggle
228
+ ?isChecked=${checked}
229
+ ?disabled=${!!field.readOnly}
230
+ @nile-change=${(e) => onInput(detailChecked(e))}
231
+ ></nile-slide-toggle>`;
232
+ });
233
+ /** `button` — an action. Keeps its label as button text; emits `aq-mcp-action`. */
234
+ registerControl('button', ({ field, onAction }) => {
235
+ return html `<nile-button variant="secondary" @click=${() => onAction?.()}>${labelOf(field)}</nile-button>`;
236
+ });
237
+ /** `nile-file-upload`'s own `subtitle` property defaults to the hardcoded,
238
+ * image-upload-specific `'PNG, JPG or SVG (upto 1MB) | 1:1 ratio'` — passing
239
+ * `allowedTypes`/`size` only affects drop/pick VALIDATION, never this
240
+ * displayed hint text, so a non-image field (a PEM certificate, say) shown
241
+ * with no override still tells the user to drop a PNG. Derives a real hint
242
+ * from the field's own `accept`/`maxSizeKB` instead: extension-like entries
243
+ * (`.pem`, `.crt`, …) are shown; bare MIME types (`application/x-pem-file`)
244
+ * are skipped since they're not something a user recognizes at a glance. */
245
+ function fileUploadSubtitle(field) {
246
+ const size = field.maxSizeKB ? `${field.maxSizeKB}KB` : '10MB';
247
+ const exts = (field.accept ?? []).filter((t) => t.startsWith('.')).map((t) => t.slice(1).toUpperCase());
248
+ if (exts.length === 0)
249
+ return `Up to ${size}`;
250
+ const list = exts.length <= 1 ? exts[0] : `${exts.slice(0, -1).join(', ')} or ${exts[exts.length - 1]}`;
251
+ return `${list} (up to ${size})`;
252
+ }
253
+ /**
254
+ * `file` — local file selection only; never uploads itself (D-4): `autoUpload`
255
+ * is forced off and no `fileUploadUrl` is ever set. Emits the picked
256
+ * `File`/`File[]` via `onInput`; the host decides how/when to send the bytes
257
+ * (`aq-mcp-submit` payload). `datatype: "array"` + `ui-component: "file"` means
258
+ * multi-file, mirroring how `array` + `select` means multi-select.
259
+ */
260
+ registerControl('file', ({ field, value, error, onInput }) => {
261
+ const multiple = field.datatype === 'array';
262
+ const files = multiple
263
+ ? Array.isArray(value) ? value : []
264
+ : value instanceof File ? [value] : [];
265
+ return html `
266
+ <nile-file-upload
267
+ .allowMultiple=${multiple}
268
+ .autoUpload=${false}
269
+ .allowedTypes=${field.accept ?? []}
270
+ .size=${field.maxSizeKB ? `${field.maxSizeKB}KB` : '10MB'}
271
+ .subtitle=${fileUploadSubtitle(field)}
272
+ .error=${!!error}
273
+ .errorMessage=${error ?? ''}
274
+ @nile-change=${(e) => {
275
+ const picked = e.detail?.files ?? [];
276
+ // Lit's first `updated()` reports every reactive property (incl. the
277
+ // `uploadedFiles: []` default) as "changed" from undefined, so the
278
+ // control fires one spurious empty nile-change on mount — ignore an
279
+ // empty-to-empty transition so that isn't mistaken for a real edit.
280
+ if (picked.length === 0 && files.length === 0)
281
+ return;
282
+ onInput(multiple ? picked : (picked[0] ?? null));
283
+ }}
284
+ ></nile-file-upload>
285
+ ${files.map((f) => html `<nile-file-preview
286
+ .inputFile=${f}
287
+ @nile-remove=${() => onInput(multiple ? files.filter((x) => x !== f) : null)}
288
+ ></nile-file-preview>`)}
289
+ `;
290
+ });
291
+ const CONNECTION_STATUS_VARIANT = {
292
+ SUCCESS: 'success',
293
+ PARTIAL: 'warning',
294
+ FAILED: 'error',
295
+ CONFIG_INVALID: 'error',
296
+ };
297
+ const CONNECTION_STATUS_HEADING = {
298
+ SUCCESS: 'Connection successful',
299
+ PARTIAL: 'Partial connection',
300
+ FAILED: 'Connection failed',
301
+ CONFIG_INVALID: 'Invalid configuration',
302
+ };
303
+ function connectionSummaryText(report) {
304
+ const heading = CONNECTION_STATUS_HEADING[report.connectionStatus] ?? 'Connection test';
305
+ const { passed, total, skipped } = report.summary;
306
+ return skipped
307
+ ? `${heading}: ${passed} of ${total} checks passed, ${skipped} skipped`
308
+ : `${heading}: ${passed} of ${total} checks passed`;
309
+ }
310
+ function formatTestedAt(iso) {
311
+ const d = new Date(iso);
312
+ if (Number.isNaN(d.getTime()))
313
+ return iso;
314
+ return d.toLocaleString(undefined, {
315
+ year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit',
316
+ });
317
+ }
318
+ function checkVisual(status) {
319
+ if (status === 'PASSED')
320
+ return 'passed';
321
+ if (status === 'SKIPPED')
322
+ return 'skipped';
323
+ return 'failed';
324
+ }
325
+ /**
326
+ * `x-circle` and `minus` are dead ends in this glyph set: nile-glyph strips
327
+ * hyphens before lookup and both names hit an alias table that redirects them
328
+ * to fill-authored icons ("error" / a bare dash), not stroke-line icons — so
329
+ * rendering them with `method="stroke"` produces a heavier, blobby look
330
+ * instead of a clean thin outline. `ng-circle-x`/`ng-circle-minus` are
331
+ * unaliased and share `check-circle`'s exact stroke width (1.6), so all three
332
+ * states render as a matched family regardless of which theme is active.
333
+ */
334
+ const CHECK_ICON = { passed: 'check-circle', failed: 'ng-circle-x', skipped: 'ng-circle-minus' };
335
+ const CHECK_BADGE_VARIANT = { passed: 'success', failed: 'error', skipped: 'gray' };
336
+ /** Icon/name/message/endpoint/badge — shared by every check row regardless of status. */
337
+ function renderCheckRow(check, visual) {
338
+ return html `
339
+ <nile-glyph
340
+ class="aq-mcp-check__icon"
341
+ name=${CHECK_ICON[visual]}
342
+ method="stroke"
343
+ size="18"
344
+ color="currentColor"
345
+ ></nile-glyph>
346
+ <div class="aq-mcp-check__body">
347
+ <div class="aq-mcp-check__name">${check.name}</div>
348
+ <div class="aq-mcp-check__message">${check.message ?? ''}</div>
349
+ </div>
350
+ <span class="aq-mcp-check__endpoint">${check.endpoint ?? ''}</span>
351
+ ${check.httpStatus != null
352
+ ? html `<nile-badge variant=${CHECK_BADGE_VARIANT[visual]} rounded>${check.httpStatus}</nile-badge>`
353
+ : ''}
354
+ `;
355
+ }
356
+ function renderCheck(check) {
357
+ const visual = checkVisual(check.status);
358
+ const row = renderCheckRow(check, visual);
359
+ // A failed check with a mitigation is a native <details>/<summary> — not
360
+ // nile-accordion — so the row shares the exact same markup/CSS as every
361
+ // other check (no risk of the accordion's own internal padding/gap for its
362
+ // built-in chevron shifting this row out of alignment with the rest).
363
+ if (visual === 'failed' && check.mitigation) {
364
+ return html `
365
+ <details class="aq-mcp-check aq-mcp-check--${visual}">
366
+ <summary class="aq-mcp-check__row">
367
+ ${row}
368
+ <nile-glyph class="aq-mcp-check__chevron" name="chevron-down" method="stroke" size="16" color="currentColor"></nile-glyph>
369
+ </summary>
370
+ <div class="aq-mcp-check__fix">
371
+ <div class="aq-mcp-check__fix-label">How to fix</div>
372
+ <div class="aq-mcp-check__fix-body">${check.mitigation}</div>
373
+ </div>
374
+ </details>
375
+ `;
376
+ }
377
+ return html `<div class="aq-mcp-check aq-mcp-check--${visual}"><div class="aq-mcp-check__row">${row}</div></div>`;
378
+ }
379
+ /**
380
+ * `test-connection-report` — read-only render of a connection-test result
381
+ * (paired with `datatype: "none"`: never validated, never submitted). The
382
+ * host runs its own connection-test tool and sets the result into
383
+ * `values[attribute]`; this control only displays it — no `onInput`/
384
+ * `onAction`, no network I/O, and no interpretation of what a failed check
385
+ * *means* beyond the host-supplied `impact` sentence (D-4).
386
+ */
387
+ registerControl('test-connection-report', ({ value }) => {
388
+ const report = value;
389
+ if (!report)
390
+ return html ``;
391
+ if (report.error) {
392
+ return html `<nile-section-message
393
+ variant="error"
394
+ heading="Connection test failed to run"
395
+ description=${report.error}
396
+ ></nile-section-message>`;
397
+ }
398
+ return html `
399
+ <div class="aq-mcp-report">
400
+ <div class="aq-mcp-report__meta">Last run ${formatTestedAt(report.testedAt)}</div>
401
+ <nile-section-message
402
+ variant=${CONNECTION_STATUS_VARIANT[report.connectionStatus] ?? 'primary'}
403
+ heading=${connectionSummaryText(report)}
404
+ description=${report.impact ?? ''}
405
+ ></nile-section-message>
406
+ <div class="aq-mcp-report__checks">${report.checks.map(renderCheck)}</div>
407
+ </div>
408
+ `;
409
+ });
410
+ let permissionsReportInstanceCounter = 0;
411
+ /**
412
+ * `permissions-report` — read-only scope/permission GRANT table (paired with
413
+ * `datatype: "none"`: never validated/submitted, same contract as
414
+ * `test-connection-report`). Distinct from that control: `test-connection-report`
415
+ * models a list of PASS/FAIL endpoint probes; this one models a validation banner
416
+ * + a running "N Granted" count + an All/Success filter + a Resource Type/
417
+ * Permission Type/Access table — matching the live reference's own "Credentials"
418
+ * tab Test Connection result exactly (confirmed live, then Cancelled the token
419
+ * dialog it also opens — see `properties-table`'s own doc comment for that half
420
+ * of the Credentials tab).
421
+ *
422
+ * The All/Success filter is pure CSS (`:nth-of-type` + the general sibling
423
+ * combinator `~`, see `mcp-ui-render.css` — no `:has()`, for broader browser
424
+ * support) — no Lit reactive state needed, same "native-state, no
425
+ * component-local state" precedent `test-connection-report`'s mitigation
426
+ * `<details>` already set. Each instance gets a unique radio-group `name` (a
427
+ * module-level counter, not `field.attribute`, since attributes can repeat across
428
+ * distinct standalone `<aq-mcp-field>` mounts in a way a plain incrementing
429
+ * counter can't collide on) so multiple reports on one page don't cross-toggle.
430
+ */
431
+ registerControl('permissions-report', ({ value }) => {
432
+ const report = value;
433
+ if (!report)
434
+ return html ``;
435
+ const uid = `pg${permissionsReportInstanceCounter++}`;
436
+ const grantedCount = report.grants.filter((g) => g.access === 'Granted').length;
437
+ return html `
438
+ <div class="aq-mcp-permissions">
439
+ <nile-section-message
440
+ variant=${report.valid ? 'success' : 'error'}
441
+ description=${report.message}
442
+ ></nile-section-message>
443
+ <div class="aq-mcp-permissions__report">
444
+ <input type="radio" name="pf-${uid}" id="pf-all-${uid}" checked class="aq-mcp-permissions__filter-input" />
445
+ <input type="radio" name="pf-${uid}" id="pf-success-${uid}" class="aq-mcp-permissions__filter-input" />
446
+ <div class="aq-mcp-permissions__report-title">Validation Report</div>
447
+ <div class="aq-mcp-permissions__toolbar">
448
+ <div class="aq-mcp-permissions__stat">
449
+ <div class="aq-mcp-permissions__stat-count">${grantedCount}</div>
450
+ <div class="aq-mcp-permissions__stat-label">Granted</div>
451
+ </div>
452
+ <div class="aq-mcp-permissions__filter-labels">
453
+ <label for="pf-all-${uid}" class="aq-mcp-permissions__filter-label">All</label>
454
+ <label for="pf-success-${uid}" class="aq-mcp-permissions__filter-label">Success</label>
455
+ </div>
456
+ </div>
457
+ <table class="aq-mcp-table aq-mcp-permissions__table">
458
+ <thead>
459
+ <tr><th>Resource Type</th><th>Permission Type</th><th>Access</th></tr>
460
+ </thead>
461
+ <tbody>
462
+ ${report.grants.map((grant) => html `<tr class="aq-mcp-permissions__row" data-access=${grant.access}>
463
+ <td>${grant.resourceType}</td>
464
+ <td>${grant.permissionType}</td>
465
+ <td><nile-badge variant=${grant.access === 'Granted' ? 'success' : 'error'} rounded>${grant.access}</nile-badge></td>
466
+ </tr>`)}
467
+ </tbody>
468
+ </table>
469
+ </div>
470
+ </div>
471
+ `;
472
+ });
473
+ /** Cell values over this length are truncated with an ellipsis (full value still
474
+ * available via the cell's `title` attribute) — a long transformation/mapping
475
+ * string is exactly the case `properties-table` exists for (see below). */
476
+ const TABLE_CELL_TRUNCATE_AT = 60;
477
+ /** Formats one `PropertiesTableRow.value` for display — never re-interprets or
478
+ * validates it (this control is read-only, D-4): `null`/`undefined` render as
479
+ * an em dash, an array joins with ", ", a plain object (e.g. a per-file header
480
+ * mapping) is JSON-stringified, and a long string is truncated with an
481
+ * ellipsis (the raw, untruncated value stays in the cell's `title` for hover). */
482
+ function formatTableValue(value) {
483
+ if (value === null || value === undefined)
484
+ return { text: '—', title: null };
485
+ const raw = Array.isArray(value)
486
+ ? value.map(String).join(', ')
487
+ : typeof value === 'object'
488
+ ? JSON.stringify(value)
489
+ : String(value);
490
+ if (raw.length <= TABLE_CELL_TRUNCATE_AT)
491
+ return { text: raw, title: null };
492
+ return { text: `${raw.slice(0, TABLE_CELL_TRUNCATE_AT)}…`, title: raw };
493
+ }
494
+ /** Property names are single-line and truncate the same way (a long
495
+ * connector-defined attribute name like `provisioningSheetNames` is exactly
496
+ * the case this exists for) — same ellipsis + hover-`title` treatment as
497
+ * `formatTableValue`, just always a plain string, never JSON-stringified. */
498
+ const TABLE_PROPERTY_TRUNCATE_AT = 24;
499
+ function formatPropertyName(property) {
500
+ if (property.length <= TABLE_PROPERTY_TRUNCATE_AT)
501
+ return { text: property, title: null };
502
+ return { text: `${property.slice(0, TABLE_PROPERTY_TRUNCATE_AT)}…`, title: property };
503
+ }
504
+ /**
505
+ * `properties-table` — a read-only card (paired with `datatype: "none"`: never
506
+ * validated, never submitted — same contract as `test-connection-report`),
507
+ * matching the live reference's "Generated Configuration" card: a header row
508
+ * (title from `field.label`, subtitle from `field.help`, a right-aligned
509
+ * toolbar from `field.actions` — see `Field.actions`'s doc comment) with a
510
+ * Property/Value table underneath. Rendered as a `FULL_WIDTH_CONTROLS` entry
511
+ * (`aq-mcp-field.ts`) — this control owns its own title/help display instead
512
+ * of `<aq-mcp-field>`'s usual label-left/control-right split, which is why the
513
+ * header renders unconditionally (same "the label is always visible somewhere"
514
+ * guarantee the two-column layout already gave every other control).
515
+ *
516
+ * Table rows come from either source, `values[attribute]` (host-supplied,
517
+ * dynamic) taking priority over `field.rows` (descriptor-declared, static)
518
+ * when both are present — same priority `dynamicOptions` has over `options`
519
+ * for `select`/`radio` (§9.6, see the `PropertiesTableRow` doc comment). No
520
+ * rows renders the header with no table beneath it, not a fully blank
521
+ * control — the header (and any actions) stays usable even before there's
522
+ * anything to show in the table (e.g. "Edit Configuration" before a sample
523
+ * file has ever been uploaded).
524
+ *
525
+ * This is the DEFAULT rendering. A host wanting different toolbar UI (button
526
+ * styling, a dropdown, extra actions chrome) doesn't need a new extensibility
527
+ * hook for that — `registerControl('properties-table', myRenderer)` overrides
528
+ * this whole function, exactly like overriding any other built-in control.
529
+ */
530
+ registerControl('properties-table', ({ field, value, onAction }) => {
531
+ const rows = (value ?? field.rows ?? []);
532
+ const actions = field.actions ?? [];
533
+ return html `
534
+ <div class="aq-mcp-table-card">
535
+ <div class="aq-mcp-table-card__header">
536
+ <div class="aq-mcp-table-card__heading">
537
+ <div class="aq-mcp-table-card__title">${labelOf(field)}</div>
538
+ ${field.help ? html `<div class="aq-mcp-table-card__subtitle">${field.help}</div>` : ''}
539
+ </div>
540
+ ${actions.length > 0
541
+ ? html `<div class="aq-mcp-table-card__actions">
542
+ ${actions.map((action) => action.icon
543
+ ? html `<nile-icon-button
544
+ name=${action.icon}
545
+ label=${action.label}
546
+ @click=${() => onAction?.(action)}
547
+ ></nile-icon-button>`
548
+ : html `<nile-button variant="secondary" @click=${() => onAction?.(action)}>${action.label}</nile-button>`)}
549
+ </div>`
550
+ : ''}
551
+ </div>
552
+ ${rows.length > 0
553
+ ? html `<table class="aq-mcp-table">
554
+ <thead>
555
+ <tr><th>Property</th><th>Value</th></tr>
556
+ </thead>
557
+ <tbody>
558
+ ${rows.map((row) => {
559
+ const property = formatPropertyName(row.property);
560
+ const value = formatTableValue(row.value);
561
+ return html `<tr>
562
+ <td class="aq-mcp-table__property" title=${property.title ?? ''}>${property.text}</td>
563
+ <td class="aq-mcp-table__value" title=${value.title ?? ''}>${value.text}</td>
564
+ </tr>`;
565
+ })}
566
+ </tbody>
567
+ </table>`
568
+ : ''}
569
+ </div>
570
+ `;
571
+ });
572
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../../apps/mcp-ui-render/src/controls.ts"],"names":[],"mappings":"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"}