@checkstack/gitops-frontend 0.3.2 → 0.3.3
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 +12 -0
- package/package.json +3 -3
- package/src/pages/KindRegistryPage.tsx +193 -150
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @checkstack/gitops-frontend
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 57d54de: Fix GitOps Healthcheck reconciliation engine and Kind Registry UI
|
|
8
|
+
|
|
9
|
+
- Mandated fully qualified IDs for all healthcheck strategies and collector definitions.
|
|
10
|
+
- Refactored the Kind Registry UI to display schema documentation in beautifully formatted, interactive YAML examples.
|
|
11
|
+
- Entity Envelope Fields and Base Spec Schema are now displayed in collapsed accordions.
|
|
12
|
+
- Fixed condition logic that broke the collector documentation display.
|
|
13
|
+
- Enhanced UX by dynamically injecting fully-qualified strategy variants directly into the YAML examples.
|
|
14
|
+
|
|
3
15
|
## 0.3.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/gitops-frontend",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"checkstack": {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@checkstack/common": "0.6.5",
|
|
16
16
|
"@checkstack/frontend-api": "0.3.9",
|
|
17
|
-
"@checkstack/gitops-common": "0.
|
|
18
|
-
"@checkstack/ui": "1.
|
|
17
|
+
"@checkstack/gitops-common": "0.2.0",
|
|
18
|
+
"@checkstack/ui": "1.5.0",
|
|
19
19
|
"lucide-react": "^0.344.0",
|
|
20
20
|
"react": "^18.2.0",
|
|
21
21
|
"react-router-dom": "^6.22.0"
|
|
@@ -13,8 +13,11 @@ import {
|
|
|
13
13
|
SelectTrigger,
|
|
14
14
|
SelectValue,
|
|
15
15
|
CodeEditor,
|
|
16
|
-
Markdown,
|
|
17
16
|
MarkdownBlock,
|
|
17
|
+
Accordion,
|
|
18
|
+
AccordionItem,
|
|
19
|
+
AccordionTrigger,
|
|
20
|
+
AccordionContent,
|
|
18
21
|
} from "@checkstack/ui";
|
|
19
22
|
import {
|
|
20
23
|
ChevronDown,
|
|
@@ -64,131 +67,48 @@ interface KindDescription {
|
|
|
64
67
|
|
|
65
68
|
// ─── Schema Display ────────────────────────────────────────────────────────
|
|
66
69
|
|
|
67
|
-
const TYPE_COLORS: Record<string, string> = {
|
|
68
|
-
string: "text-green-600 dark:text-green-400",
|
|
69
|
-
number: "text-amber-600 dark:text-amber-400",
|
|
70
|
-
integer: "text-amber-600 dark:text-amber-400",
|
|
71
|
-
boolean: "text-red-600 dark:text-red-400",
|
|
72
|
-
array: "text-blue-600 dark:text-blue-400",
|
|
73
|
-
object: "text-purple-600 dark:text-purple-400",
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
function SchemaPropertyDisplay({
|
|
77
|
-
schema,
|
|
78
|
-
depth = 0,
|
|
79
|
-
}: {
|
|
80
|
-
schema: JsonSchemaProperty;
|
|
81
|
-
depth?: number;
|
|
82
|
-
}) {
|
|
83
|
-
if (schema.enum) {
|
|
84
|
-
return (
|
|
85
|
-
<span className="text-green-600 dark:text-green-400">
|
|
86
|
-
{schema.enum.map((e) => `"${e}"`).join(" | ")}
|
|
87
|
-
</span>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
70
|
|
|
91
|
-
if (schema.anyOf) {
|
|
92
|
-
return (
|
|
93
|
-
<span>
|
|
94
|
-
{schema.anyOf.map((s, i) => (
|
|
95
|
-
<span key={i}>
|
|
96
|
-
{i > 0 && <span className="text-muted-foreground"> | </span>}
|
|
97
|
-
<SchemaPropertyDisplay schema={s} depth={depth} />
|
|
98
|
-
</span>
|
|
99
|
-
))}
|
|
100
|
-
</span>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
71
|
|
|
72
|
+
function generateSchemaYaml(schema: JsonSchemaProperty): string {
|
|
73
|
+
const lines: string[] = [];
|
|
74
|
+
|
|
104
75
|
if (schema.type === "object" && schema.properties) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
</div>
|
|
124
|
-
))}
|
|
125
|
-
{"}"}
|
|
126
|
-
</div>
|
|
127
|
-
);
|
|
76
|
+
const required = new Set(schema.required);
|
|
77
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
78
|
+
emitProperty({
|
|
79
|
+
lines,
|
|
80
|
+
key,
|
|
81
|
+
prop,
|
|
82
|
+
indent: 0,
|
|
83
|
+
required: required.has(key),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
emitProperty({
|
|
88
|
+
lines,
|
|
89
|
+
key: "value",
|
|
90
|
+
prop: schema,
|
|
91
|
+
indent: 0,
|
|
92
|
+
required: true,
|
|
93
|
+
});
|
|
128
94
|
}
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
return
|
|
132
|
-
<span>
|
|
133
|
-
<SchemaPropertyDisplay schema={schema.items} depth={depth} />
|
|
134
|
-
{"[]"}
|
|
135
|
-
</span>
|
|
136
|
-
);
|
|
95
|
+
|
|
96
|
+
if (lines.length === 0) {
|
|
97
|
+
return "# No properties defined";
|
|
137
98
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<span className={TYPE_COLORS[typeStr] ?? "text-gray-600"}>
|
|
142
|
-
{typeStr}
|
|
143
|
-
{schema.default !== undefined && (
|
|
144
|
-
<span className="text-muted-foreground ml-1">
|
|
145
|
-
= {JSON.stringify(schema.default)}
|
|
146
|
-
</span>
|
|
147
|
-
)}
|
|
148
|
-
</span>
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function SchemaBlock({
|
|
153
|
-
schema,
|
|
154
|
-
label,
|
|
155
|
-
}: {
|
|
156
|
-
schema: JsonSchemaProperty;
|
|
157
|
-
label: string;
|
|
158
|
-
}) {
|
|
159
|
-
const hasProperties =
|
|
160
|
-
schema.type === "object" &&
|
|
161
|
-
schema.properties &&
|
|
162
|
-
Object.keys(schema.properties).length > 0;
|
|
163
|
-
|
|
164
|
-
if (!hasProperties) {
|
|
165
|
-
return (
|
|
166
|
-
<div>
|
|
167
|
-
<h4 className="text-sm font-medium mb-2 text-muted-foreground">
|
|
168
|
-
{label}
|
|
169
|
-
</h4>
|
|
170
|
-
<div className="bg-muted rounded-md p-3 text-sm text-muted-foreground italic">
|
|
171
|
-
No properties defined
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
<div>
|
|
179
|
-
<h4 className="text-sm font-medium mb-2 text-muted-foreground">
|
|
180
|
-
{label}
|
|
181
|
-
</h4>
|
|
182
|
-
<div className="bg-muted rounded-md p-3 overflow-x-auto">
|
|
183
|
-
<SchemaPropertyDisplay schema={schema} />
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
);
|
|
99
|
+
|
|
100
|
+
return lines.join("\n");
|
|
187
101
|
}
|
|
188
102
|
|
|
189
103
|
// ─── YAML Example Generator ────────────────────────────────────────────────
|
|
190
104
|
|
|
191
|
-
function generateYamlExample({
|
|
105
|
+
function generateYamlExample({
|
|
106
|
+
kind,
|
|
107
|
+
selections,
|
|
108
|
+
}: {
|
|
109
|
+
kind: KindDescription;
|
|
110
|
+
selections?: Record<string, string>;
|
|
111
|
+
}): string {
|
|
192
112
|
const lines = [`apiVersion: ${kind.apiVersion}`, `kind: ${kind.kind}`];
|
|
193
113
|
|
|
194
114
|
if (kind.metadataSchema) {
|
|
@@ -234,6 +154,9 @@ function generateYamlExample({ kind }: { kind: KindDescription }): string {
|
|
|
234
154
|
prop,
|
|
235
155
|
indent: 2,
|
|
236
156
|
required: baseRequired.has(key),
|
|
157
|
+
path: key,
|
|
158
|
+
kind,
|
|
159
|
+
selections,
|
|
237
160
|
});
|
|
238
161
|
}
|
|
239
162
|
|
|
@@ -260,18 +183,34 @@ function emitProperty({
|
|
|
260
183
|
prop,
|
|
261
184
|
indent,
|
|
262
185
|
required,
|
|
186
|
+
path,
|
|
187
|
+
kind,
|
|
188
|
+
selections,
|
|
263
189
|
}: {
|
|
264
190
|
lines: string[];
|
|
265
191
|
key: string;
|
|
266
192
|
prop: JsonSchemaProperty;
|
|
267
193
|
indent: number;
|
|
268
194
|
required: boolean;
|
|
195
|
+
path?: string;
|
|
196
|
+
kind?: KindDescription;
|
|
197
|
+
selections?: Record<string, string>;
|
|
269
198
|
}) {
|
|
270
199
|
const pad = " ".repeat(indent);
|
|
271
|
-
const annotation = buildAnnotation({ prop, required });
|
|
272
200
|
|
|
273
|
-
|
|
274
|
-
|
|
201
|
+
let effectiveProp = prop;
|
|
202
|
+
if (path && kind?.specSchemaDocumentation && selections && selections[path]) {
|
|
203
|
+
const variantId = selections[path];
|
|
204
|
+
const doc = kind.specSchemaDocumentation.find(
|
|
205
|
+
(d) => d.fieldPath === path && (d.variantId || d.label) === variantId
|
|
206
|
+
);
|
|
207
|
+
if (doc) {
|
|
208
|
+
effectiveProp = doc.specSchema;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const annotation = buildAnnotation({ prop: effectiveProp, required });
|
|
213
|
+
const effective = resolveEffective({ prop: effectiveProp });
|
|
275
214
|
|
|
276
215
|
if (effective.type === "object" && effective.properties) {
|
|
277
216
|
lines.push(`${pad}${key}:${annotation}`);
|
|
@@ -283,17 +222,36 @@ function emitProperty({
|
|
|
283
222
|
prop: p,
|
|
284
223
|
indent: indent + 2,
|
|
285
224
|
required: objRequired.has(k),
|
|
225
|
+
path: path ? `${path}.${k}` : undefined,
|
|
226
|
+
kind,
|
|
227
|
+
selections,
|
|
286
228
|
});
|
|
287
229
|
}
|
|
288
230
|
} else if (effective.type === "array") {
|
|
289
231
|
lines.push(`${pad}${key}:${annotation}`);
|
|
290
232
|
if (effective.items) {
|
|
291
|
-
emitArrayItem({
|
|
233
|
+
emitArrayItem({
|
|
234
|
+
lines,
|
|
235
|
+
itemSchema: effective.items,
|
|
236
|
+
indent: indent + 2,
|
|
237
|
+
path: path ? `${path}[]` : undefined,
|
|
238
|
+
kind,
|
|
239
|
+
selections,
|
|
240
|
+
});
|
|
292
241
|
} else {
|
|
293
242
|
lines.push(`${pad} - # ...`);
|
|
294
243
|
}
|
|
295
244
|
} else {
|
|
296
|
-
|
|
245
|
+
let val = scalarExample({ prop: effective });
|
|
246
|
+
|
|
247
|
+
if (key === "strategy" && path === "strategy" && selections?.["config"]) {
|
|
248
|
+
val = `"${selections["config"]}"`;
|
|
249
|
+
}
|
|
250
|
+
if (key === "collectorId" && path === "collectors[].collectorId" && selections?.["collectors[].config"]) {
|
|
251
|
+
val = `"${selections["collectors[].config"]}"`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
lines.push(`${pad}${key}: ${val}${annotation}`);
|
|
297
255
|
}
|
|
298
256
|
}
|
|
299
257
|
|
|
@@ -305,10 +263,16 @@ function emitArrayItem({
|
|
|
305
263
|
lines,
|
|
306
264
|
itemSchema,
|
|
307
265
|
indent,
|
|
266
|
+
path,
|
|
267
|
+
kind,
|
|
268
|
+
selections,
|
|
308
269
|
}: {
|
|
309
270
|
lines: string[];
|
|
310
271
|
itemSchema: JsonSchemaProperty;
|
|
311
272
|
indent: number;
|
|
273
|
+
path?: string;
|
|
274
|
+
kind?: KindDescription;
|
|
275
|
+
selections?: Record<string, string>;
|
|
312
276
|
}) {
|
|
313
277
|
const pad = " ".repeat(indent);
|
|
314
278
|
const effective = resolveEffective({ prop: itemSchema });
|
|
@@ -318,11 +282,25 @@ function emitArrayItem({
|
|
|
318
282
|
const entries = Object.entries(effective.properties);
|
|
319
283
|
for (const [i, [k, p]] of entries.entries()) {
|
|
320
284
|
const prefix = i === 0 ? `${pad}- ` : `${pad} `;
|
|
285
|
+
|
|
286
|
+
const nextPath = path ? (path.endsWith("[]") ? `${path}.${k}` : `${path}[].${k}`) : undefined;
|
|
287
|
+
|
|
288
|
+
let currentProp = p;
|
|
289
|
+
if (nextPath && kind?.specSchemaDocumentation && selections && selections[nextPath]) {
|
|
290
|
+
const variantId = selections[nextPath];
|
|
291
|
+
const doc = kind.specSchemaDocumentation.find(
|
|
292
|
+
(d) => d.fieldPath === nextPath && (d.variantId || d.label) === variantId
|
|
293
|
+
);
|
|
294
|
+
if (doc) {
|
|
295
|
+
currentProp = doc.specSchema;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
321
299
|
const itemAnnotation = buildAnnotation({
|
|
322
|
-
prop:
|
|
300
|
+
prop: currentProp,
|
|
323
301
|
required: itemRequired.has(k),
|
|
324
302
|
});
|
|
325
|
-
const inner = resolveEffective({ prop:
|
|
303
|
+
const inner = resolveEffective({ prop: currentProp });
|
|
326
304
|
|
|
327
305
|
if (inner.type === "object" && inner.properties) {
|
|
328
306
|
// Recurse into nested objects
|
|
@@ -335,18 +313,32 @@ function emitArrayItem({
|
|
|
335
313
|
prop: np,
|
|
336
314
|
indent: indent + 4,
|
|
337
315
|
required: nestedRequired.has(nk),
|
|
316
|
+
path: nextPath ? `${nextPath}.${nk}` : undefined,
|
|
317
|
+
kind,
|
|
318
|
+
selections,
|
|
338
319
|
});
|
|
339
320
|
}
|
|
340
321
|
} else if (inner.type === "array") {
|
|
341
322
|
lines.push(`${prefix}${k}:${itemAnnotation}`);
|
|
342
323
|
if (inner.items) {
|
|
343
|
-
emitArrayItem({
|
|
324
|
+
emitArrayItem({
|
|
325
|
+
lines,
|
|
326
|
+
itemSchema: inner.items,
|
|
327
|
+
indent: indent + 4,
|
|
328
|
+
path: nextPath ? `${nextPath}[]` : undefined,
|
|
329
|
+
kind,
|
|
330
|
+
selections,
|
|
331
|
+
});
|
|
344
332
|
} else {
|
|
345
333
|
lines.push(`${" ".repeat(indent + 4)}- # ...`);
|
|
346
334
|
}
|
|
347
335
|
} else {
|
|
336
|
+
let val = scalarExample({ prop: currentProp });
|
|
337
|
+
if (k === "collectorId" && nextPath === "collectors[].collectorId" && selections?.["collectors[].config"]) {
|
|
338
|
+
val = `"${selections["collectors[].config"]}"`;
|
|
339
|
+
}
|
|
348
340
|
lines.push(
|
|
349
|
-
`${prefix}${k}: ${
|
|
341
|
+
`${prefix}${k}: ${val}${itemAnnotation}`,
|
|
350
342
|
);
|
|
351
343
|
}
|
|
352
344
|
}
|
|
@@ -402,7 +394,7 @@ function resolveEffective({
|
|
|
402
394
|
*/
|
|
403
395
|
function scalarExample({ prop }: { prop: JsonSchemaProperty }): string {
|
|
404
396
|
const effective = resolveEffective({ prop });
|
|
405
|
-
if (effective.enum) return `"${
|
|
397
|
+
if (effective.enum) return effective.enum.map((e) => `"${e}"`).join(" | ");
|
|
406
398
|
if (effective.default !== undefined) return JSON.stringify(effective.default);
|
|
407
399
|
switch (effective.type) {
|
|
408
400
|
case "string": {
|
|
@@ -432,18 +424,13 @@ function scalarExample({ prop }: { prop: JsonSchemaProperty }): string {
|
|
|
432
424
|
|
|
433
425
|
function SpecSchemaDocumentationSection({
|
|
434
426
|
docs,
|
|
427
|
+
selections,
|
|
428
|
+
onSelect,
|
|
435
429
|
}: {
|
|
436
430
|
docs: NonNullable<KindDescription["specSchemaDocumentation"]>;
|
|
431
|
+
selections: Record<string, string>;
|
|
432
|
+
onSelect: (fieldPath: string, variantId: string) => void;
|
|
437
433
|
}) {
|
|
438
|
-
const [selections, setSelections] = useState<Record<string, string>>({});
|
|
439
|
-
|
|
440
|
-
const handleSelect = useCallback((fieldPath: string, variantId: string) => {
|
|
441
|
-
setSelections((prev) => {
|
|
442
|
-
if (prev[fieldPath] === variantId) return prev;
|
|
443
|
-
return { ...prev, [fieldPath]: variantId };
|
|
444
|
-
});
|
|
445
|
-
}, []);
|
|
446
|
-
|
|
447
434
|
const groupedDocs: Record<string, typeof docs> = {};
|
|
448
435
|
for (const doc of docs) {
|
|
449
436
|
if (!groupedDocs[doc.fieldPath]) {
|
|
@@ -466,7 +453,7 @@ function SpecSchemaDocumentationSection({
|
|
|
466
453
|
fieldPath={fieldPath}
|
|
467
454
|
docs={fieldDocs.toSorted((a, b) => a.label.localeCompare(b.label))}
|
|
468
455
|
selections={selections}
|
|
469
|
-
onSelect={
|
|
456
|
+
onSelect={onSelect}
|
|
470
457
|
/>
|
|
471
458
|
);
|
|
472
459
|
})}
|
|
@@ -553,8 +540,14 @@ function SpecSchemaDocumentationField({
|
|
|
553
540
|
<MarkdownBlock>{selectedDoc.description}</MarkdownBlock>
|
|
554
541
|
</div>
|
|
555
542
|
)}
|
|
556
|
-
<div className="
|
|
557
|
-
<
|
|
543
|
+
<div className="rounded-md overflow-hidden border border-input">
|
|
544
|
+
<CodeEditor
|
|
545
|
+
value={generateSchemaYaml(selectedDoc.specSchema)}
|
|
546
|
+
language="yaml"
|
|
547
|
+
readOnly
|
|
548
|
+
onChange={() => {}}
|
|
549
|
+
minHeight={`${Math.max(100, generateSchemaYaml(selectedDoc.specSchema).split("\n").length * 20 + 20)}px`}
|
|
550
|
+
/>
|
|
558
551
|
</div>
|
|
559
552
|
</div>
|
|
560
553
|
) : (
|
|
@@ -570,7 +563,16 @@ function SpecSchemaDocumentationField({
|
|
|
570
563
|
|
|
571
564
|
function KindCard({ kind }: { kind: KindDescription }) {
|
|
572
565
|
const [isOpen, setIsOpen] = useState(false);
|
|
573
|
-
const
|
|
566
|
+
const [selections, setSelections] = useState<Record<string, string>>({});
|
|
567
|
+
|
|
568
|
+
const handleSelect = useCallback((fieldPath: string, variantId: string) => {
|
|
569
|
+
setSelections((prev) => {
|
|
570
|
+
if (prev[fieldPath] === variantId) return prev;
|
|
571
|
+
return { ...prev, [fieldPath]: variantId };
|
|
572
|
+
});
|
|
573
|
+
}, []);
|
|
574
|
+
|
|
575
|
+
const yamlExample = useMemo(() => generateYamlExample({ kind, selections }), [kind, selections]);
|
|
574
576
|
|
|
575
577
|
return (
|
|
576
578
|
<Card className="mb-3">
|
|
@@ -610,14 +612,47 @@ function KindCard({ kind }: { kind: KindDescription }) {
|
|
|
610
612
|
|
|
611
613
|
{isOpen && (
|
|
612
614
|
<CardContent className="pt-0 space-y-6">
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
615
|
+
<Accordion type="multiple">
|
|
616
|
+
{/* Entity Envelope Fields */}
|
|
617
|
+
<AccordionItem value="envelope" className="border-b-0">
|
|
618
|
+
<AccordionTrigger className="py-2 hover:no-underline">
|
|
619
|
+
<h4 className="text-sm font-medium text-muted-foreground">
|
|
620
|
+
Entity Envelope Fields
|
|
621
|
+
</h4>
|
|
622
|
+
</AccordionTrigger>
|
|
623
|
+
<AccordionContent>
|
|
624
|
+
<div className="rounded-md overflow-hidden border border-input mt-2">
|
|
625
|
+
<CodeEditor
|
|
626
|
+
value={generateSchemaYaml(kind.metadataSchema)}
|
|
627
|
+
language="yaml"
|
|
628
|
+
readOnly
|
|
629
|
+
onChange={() => {}}
|
|
630
|
+
minHeight={`${Math.max(100, generateSchemaYaml(kind.metadataSchema).split("\n").length * 20 + 20)}px`}
|
|
631
|
+
/>
|
|
632
|
+
</div>
|
|
633
|
+
</AccordionContent>
|
|
634
|
+
</AccordionItem>
|
|
635
|
+
|
|
636
|
+
{/* Base Spec Schema */}
|
|
637
|
+
<AccordionItem value="base-spec" className="border-b-0">
|
|
638
|
+
<AccordionTrigger className="py-2 hover:no-underline">
|
|
639
|
+
<h4 className="text-sm font-medium text-muted-foreground">
|
|
640
|
+
Base Spec Schema
|
|
641
|
+
</h4>
|
|
642
|
+
</AccordionTrigger>
|
|
643
|
+
<AccordionContent>
|
|
644
|
+
<div className="rounded-md overflow-hidden border border-input mt-2">
|
|
645
|
+
<CodeEditor
|
|
646
|
+
value={generateSchemaYaml(kind.specSchema)}
|
|
647
|
+
language="yaml"
|
|
648
|
+
readOnly
|
|
649
|
+
onChange={() => {}}
|
|
650
|
+
minHeight={`${Math.max(100, generateSchemaYaml(kind.specSchema).split("\n").length * 20 + 20)}px`}
|
|
651
|
+
/>
|
|
652
|
+
</div>
|
|
653
|
+
</AccordionContent>
|
|
654
|
+
</AccordionItem>
|
|
655
|
+
</Accordion>
|
|
621
656
|
|
|
622
657
|
{/* Extensions */}
|
|
623
658
|
{kind.extensions.length > 0 && (
|
|
@@ -636,8 +671,14 @@ function KindCard({ kind }: { kind: KindDescription }) {
|
|
|
636
671
|
{ext.namespace}
|
|
637
672
|
</Badge>
|
|
638
673
|
</div>
|
|
639
|
-
<div className="
|
|
640
|
-
<
|
|
674
|
+
<div className="rounded-md overflow-hidden border border-input">
|
|
675
|
+
<CodeEditor
|
|
676
|
+
value={generateSchemaYaml(ext.specSchema)}
|
|
677
|
+
language="yaml"
|
|
678
|
+
readOnly
|
|
679
|
+
onChange={() => {}}
|
|
680
|
+
minHeight={`${Math.max(100, generateSchemaYaml(ext.specSchema).split("\n").length * 20 + 20)}px`}
|
|
681
|
+
/>
|
|
641
682
|
</div>
|
|
642
683
|
</div>
|
|
643
684
|
))}
|
|
@@ -649,6 +690,8 @@ function KindCard({ kind }: { kind: KindDescription }) {
|
|
|
649
690
|
kind.specSchemaDocumentation.length > 0 && (
|
|
650
691
|
<SpecSchemaDocumentationSection
|
|
651
692
|
docs={kind.specSchemaDocumentation}
|
|
693
|
+
selections={selections}
|
|
694
|
+
onSelect={handleSelect}
|
|
652
695
|
/>
|
|
653
696
|
)}
|
|
654
697
|
|