feat: connect wizard live flow to admin api
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
<script src="../../js/api.js"></script>
|
||||
<script src="../../js/auth.js"></script>
|
||||
<script>window.CrankAuth.guardProtectedPage();</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-yaml@4.1.0/dist/js-yaml.min.js"></script>
|
||||
<script src="../../js/vendor/js-yaml/js-yaml.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="protocol-card-name">GraphQL</div>
|
||||
<div class="protocol-card-tagline">Query and mutate a GraphQL schema. Supports queries, mutations, and subscriptions.</div>
|
||||
<div class="protocol-card-tagline">Query and mutate a GraphQL schema. Supports queries and mutations over one fixed operation.</div>
|
||||
<div class="protocol-card-tags">
|
||||
<span class="protocol-tag">Query</span>
|
||||
<span class="protocol-tag">Mutation</span>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</button>
|
||||
<button class="grpc-source-btn" data-source="reflection" onclick="selectGrpcSource('reflection')">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="2.5"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.1 3.1l1.4 1.4M11.5 11.5l1.4 1.4M3.1 12.9l1.4-1.4M11.5 4.5l1.4-1.4"/></svg>
|
||||
Server reflection
|
||||
Descriptor set
|
||||
</button>
|
||||
<button class="grpc-source-btn" data-source="manual" onclick="selectGrpcSource('manual')">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M11 2l3 3-8 8H3v-3l8-8z"/></svg>
|
||||
@@ -106,8 +106,8 @@
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="2.5"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.1 3.1l1.4 1.4M11.5 11.5l1.4 1.4M3.1 12.9l1.4-1.4M11.5 4.5l1.4-1.4"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="config-card-title">Server reflection</div>
|
||||
<div class="config-card-subtitle">Discover services from the upstream gRPC server at runtime</div>
|
||||
<div class="config-card-title">Descriptor-driven discovery</div>
|
||||
<div class="config-card-subtitle">Use the saved draft and a descriptor set to discover services through the backend</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-card-body" style="gap: 14px; padding: 16px;">
|
||||
@@ -123,7 +123,7 @@
|
||||
<div id="grpc-reflect-idle">
|
||||
<button class="btn-primary-sm" onclick="startReflection()">
|
||||
<svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" style="margin-right:4px"><circle cx="8" cy="8" r="2.5"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2"/></svg>
|
||||
Discover methods
|
||||
Open live descriptor tools
|
||||
</button>
|
||||
</div>
|
||||
<!-- Loading -->
|
||||
@@ -137,7 +137,7 @@
|
||||
<div id="grpc-reflect-error" style="display:none">
|
||||
<div class="grpc-reflect-error-row">
|
||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="var(--error,#f87171)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="7"/><path d="M8 5v3M8 10.5v.5"/></svg>
|
||||
<span id="grpc-reflect-error-text">Reflection not available on this server.</span>
|
||||
<span id="grpc-reflect-error-text">Live descriptor discovery is handled in step 5.</span>
|
||||
<button class="proto-file-change" onclick="startReflection()">Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -87,15 +87,183 @@ tls:
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section-divider" style="margin-bottom: 16px;">
|
||||
<span class="section-divider-label">Live validation and publishing</span>
|
||||
<div class="section-divider-line"></div>
|
||||
</div>
|
||||
|
||||
<div id="wizard-live-status" class="info-callout" style="margin-bottom: 20px; display:none;">
|
||||
<svg class="info-callout-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="8" cy="8" r="7"/>
|
||||
<path d="M8 11V8M8 5v-.5"/>
|
||||
</svg>
|
||||
<div class="info-callout-body">
|
||||
<div class="info-callout-title" id="wizard-live-status-title">Draft actions</div>
|
||||
<div class="info-callout-text" id="wizard-live-status-text"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-card" style="margin-bottom: 20px;">
|
||||
<div class="config-card-header">
|
||||
<div class="config-card-header-icon">
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="2" y="3" width="12" height="10" rx="1.5"/>
|
||||
<path d="M5 7h6M5 10h6"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="config-card-title">Samples and draft generation</div>
|
||||
<div class="config-card-subtitle">Persist input/output samples, then generate schemas and mappings from real payloads.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-card-body" style="gap: 16px;">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Input sample</label>
|
||||
<textarea id="wizard-input-sample" class="form-textarea code-textarea" rows="9" spellcheck="false">{
|
||||
"first_name": "Ada",
|
||||
"last_name": "Lovelace",
|
||||
"email": "ada@example.com"
|
||||
}</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Output sample</label>
|
||||
<textarea id="wizard-output-sample" class="form-textarea code-textarea" rows="9" spellcheck="false">{
|
||||
"id": "lead_123",
|
||||
"status": "created"
|
||||
}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
||||
<button id="wizard-upload-input-sample" class="btn-primary-sm" type="button">Save input sample</button>
|
||||
<button id="wizard-upload-output-sample" class="btn-ghost-sm" type="button">Save output sample</button>
|
||||
<button id="wizard-generate-draft" class="btn-ghost-sm" type="button">Generate draft from samples</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-card" style="margin-bottom: 20px;">
|
||||
<div class="config-card-header">
|
||||
<div class="config-card-header-icon">
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 8h12M10 4l4 4-4 4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="config-card-title">Test run</div>
|
||||
<div class="config-card-subtitle">Run the current draft against the upstream before publishing it.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-card-body" style="gap: 16px;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Test input payload</label>
|
||||
<textarea id="wizard-test-input" class="form-textarea code-textarea" rows="8" spellcheck="false">{
|
||||
"first_name": "Ada",
|
||||
"last_name": "Lovelace",
|
||||
"email": "ada@example.com"
|
||||
}</textarea>
|
||||
</div>
|
||||
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
||||
<button id="wizard-run-test" class="btn-primary-sm" type="button">Run test</button>
|
||||
<button id="wizard-copy-test-response" class="btn-ghost-sm" type="button">Use response as output sample</button>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Request preview</label>
|
||||
<textarea id="wizard-test-request-preview" class="form-textarea code-textarea" rows="8" spellcheck="false" readonly></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Response preview</label>
|
||||
<textarea id="wizard-test-response-preview" class="form-textarea code-textarea" rows="8" spellcheck="false" readonly></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Errors</label>
|
||||
<textarea id="wizard-test-errors" class="form-textarea code-textarea" rows="4" spellcheck="false" readonly></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wizard-grpc-live-tools" class="config-card" style="margin-bottom: 20px; display:none;">
|
||||
<div class="config-card-header">
|
||||
<div class="config-card-header-icon">
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 2H4a1 1 0 00-1 1v10a1 1 0 001 1h8a1 1 0 001-1V6z"/>
|
||||
<path d="M9 2v4h4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="config-card-title">gRPC descriptor set</div>
|
||||
<div class="config-card-subtitle">Upload a compiled descriptor set and discover unary methods from the saved draft.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-card-body" style="gap: 16px;">
|
||||
<div style="display:flex; gap: 8px; align-items:center; flex-wrap: wrap;">
|
||||
<input id="wizard-descriptor-set-input" type="file" accept=".bin,.pb,.desc,.protoset,application/octet-stream" style="display:none">
|
||||
<button id="wizard-select-descriptor-set" class="btn-ghost-sm" type="button">Choose descriptor set</button>
|
||||
<button id="wizard-upload-descriptor-set" class="btn-primary-sm" type="button">Upload and discover services</button>
|
||||
<span id="wizard-descriptor-set-name" style="color: var(--text-muted); font-size: 12px;">No descriptor set selected</span>
|
||||
</div>
|
||||
<div id="wizard-descriptor-services-summary" class="form-hint"></div>
|
||||
<div id="wizard-descriptor-services-list" style="display:grid; gap: 10px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-card" style="margin-bottom: 20px;">
|
||||
<div class="config-card-header">
|
||||
<div class="config-card-header-icon">
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8 2v12M3 7l5-5 5 5"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="config-card-title">YAML import and export</div>
|
||||
<div class="config-card-subtitle">Move operation drafts between environments without leaving the wizard.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-card-body" style="gap: 16px;">
|
||||
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
||||
<button id="wizard-export-yaml" class="btn-ghost-sm" type="button">Export YAML</button>
|
||||
<button id="wizard-import-yaml-file-trigger" class="btn-ghost-sm" type="button">Load YAML file</button>
|
||||
<button id="wizard-import-yaml" class="btn-primary-sm" type="button">Import YAML</button>
|
||||
<input id="wizard-import-yaml-file" type="file" accept=".yaml,.yml,text/yaml" style="display:none">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">YAML document</label>
|
||||
<textarea id="wizard-import-yaml-text" class="form-textarea code-textarea" rows="10" spellcheck="false" placeholder="Paste exported YAML here to create or upsert an operation."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-card" style="margin-bottom: 20px;">
|
||||
<div class="config-card-header">
|
||||
<div class="config-card-header-icon">
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="var(--text-secondary)" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M3 8l3 3 7-7"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div class="config-card-title">Publish</div>
|
||||
<div class="config-card-subtitle">Save the current draft and expose it to published agents.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-card-body" style="gap: 12px;">
|
||||
<div class="form-hint">Publishing uses the current draft version from this wizard session.</div>
|
||||
<div style="display:flex; gap: 8px; flex-wrap: wrap;">
|
||||
<button id="wizard-publish-operation" class="btn-primary-sm" type="button">Publish operation</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-callout" style="margin-bottom: 24px;">
|
||||
<svg class="info-callout-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="8" cy="8" r="7"/>
|
||||
<path d="M8 11V8M8 5v-.5"/>
|
||||
</svg>
|
||||
<div class="info-callout-body">
|
||||
<div class="info-callout-title">Operation will be saved as a draft</div>
|
||||
<div class="info-callout-title">Operation stays editable in this wizard</div>
|
||||
<div class="info-callout-text">
|
||||
Clicking "Create operation" saves the contract in draft status. You can run tests, inspect metadata and publish from the operation workspace. Drafts are never exposed to MCP clients.
|
||||
Saving creates or updates the current draft in place. Use the live actions above to upload samples, test the draft, export or import YAML, and publish when the upstream contract is ready.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user