@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.
- package/CHANGELOG.md +437 -0
- package/CONFIGURATION.md +178 -0
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/RELEASE-NOTES.md +77 -0
- package/TEST-PLAN.md +72 -0
- package/USAGE.md +100 -0
- package/package.json +52 -0
- package/src/controls.d.ts +1 -0
- package/src/controls.js +572 -0
- package/src/controls.js.map +1 -0
- package/src/elements/aq-mcp-config.d.ts +289 -0
- package/src/elements/aq-mcp-config.js +673 -0
- package/src/elements/aq-mcp-config.js.map +1 -0
- package/src/elements/aq-mcp-field.d.ts +92 -0
- package/src/elements/aq-mcp-field.js +275 -0
- package/src/elements/aq-mcp-field.js.map +1 -0
- package/src/elements/aq-mcp-section.d.ts +101 -0
- package/src/elements/aq-mcp-section.js +261 -0
- package/src/elements/aq-mcp-section.js.map +1 -0
- package/src/engine/status.d.ts +31 -0
- package/src/engine/status.js +44 -0
- package/src/engine/status.js.map +1 -0
- package/src/engine/submit.d.ts +26 -0
- package/src/engine/submit.js +37 -0
- package/src/engine/submit.js.map +1 -0
- package/src/engine/validate.d.ts +24 -0
- package/src/engine/validate.js +144 -0
- package/src/engine/validate.js.map +1 -0
- package/src/engine/values.d.ts +20 -0
- package/src/engine/values.js +42 -0
- package/src/engine/values.js.map +1 -0
- package/src/index.d.ts +18 -0
- package/src/index.js +20 -0
- package/src/index.js.map +1 -0
- package/src/mcp-ui-render.css +811 -0
- package/src/registry.d.ts +63 -0
- package/src/registry.js +39 -0
- package/src/registry.js.map +1 -0
- package/src/types.d.ts +239 -0
- package/src/types.js +8 -0
- package/src/types.js.map +1 -0
package/src/controls.js
ADDED
|
@@ -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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"}
|