Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #24

Merged
merged 2 commits into from
Feb 10, 2025
Merged

Dev #24

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
@using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Triggers
@using Blocktrust.CredentialWorkflow.Web.Services
@using System.Web
@inject NavigationManager NavigationManager
@inject ClipboardService ClipboardService

<div class="w-full bg-white rounded-lg shadow-sm border border-slate-200">
<div class="flex items-center justify-between p-3 border-b border-slate-200 bg-gray-50">
<h3 class="text-sm font-medium text-gray-900">HTTP Endpoint Reference</h3>
<button @onclick="() => isExpanded = !isExpanded"
class="text-gray-500 hover:text-gray-700 p-1 hover:bg-gray-100 rounded">
<span class="material-symbols-outlined text-sm">@(isExpanded ? "expand_less" : "expand_more")</span>
</button>
</div>

@if (isExpanded)
{
<div class="p-3 space-y-3">
@if (showCopiedMessage)
{
<div class="bg-green-50 text-green-800 p-2 rounded text-sm">
Copied to clipboard!
</div>
}

<!-- Endpoint URL -->
<div>
<div class="flex items-center justify-between mb-1">
<span class="text-xs font-medium text-gray-700">Endpoint Details</span>
<button @onclick="() => CopyToClipboard(FullUrl)"
class="p-1 hover:bg-gray-100 rounded"
title="Copy URL">
<span class="material-symbols-outlined text-gray-500 text-sm">content_copy</span>
</button>
</div>
<div class="bg-gray-50 p-2 rounded">
<div class="font-mono text-sm text-gray-600 mb-1">Method: @TriggerInput.Method</div>
<div class="font-mono text-sm text-gray-600 break-all">@DisplayUrl</div>
</div>
</div>

<!-- cURL Command -->
<div>
<div class="flex items-center justify-between mb-1">
<span class="text-xs font-medium text-gray-700">cURL Example</span>
<button @onclick="() => CopyToClipboard(CurlCommand)"
class="p-1 hover:bg-gray-100 rounded"
title="Copy cURL command">
<span class="material-symbols-outlined text-gray-500 text-sm">content_copy</span>
</button>
</div>
<div class="bg-gray-50 p-2 rounded">
<pre class="font-mono text-sm text-gray-600 whitespace-pre-wrap break-all">@CurlCommand</pre>
</div>
</div>

<!-- JSON Schema -->
<div>
<div class="flex items-center justify-between mb-1">
<span class="text-xs font-medium text-gray-700">Request Schema</span>
<button @onclick="() => CopyToClipboard(JsonSchema)"
class="p-1 hover:bg-gray-100 rounded"
title="Copy complete JSON schema">
<span class="material-symbols-outlined text-gray-500 text-sm">content_copy</span>
</button>
</div>
<div class="bg-gray-50 p-2 rounded">
<pre class="font-mono text-sm text-gray-600 whitespace-pre-wrap break-all">@TruncatedJsonSchema</pre>
</div>
</div>
</div>
}
</div>

@code {
[Parameter] public Guid WorkflowId { get; set; }
[Parameter] public TriggerInputHttpRequest TriggerInput { get; set; } = null!;

private bool showCopiedMessage;
private bool isExpanded = true;

private string FullUrl => $"{NavigationManager.BaseUri.TrimEnd('/')}/api/workflow/{WorkflowId}";
private string DisplayUrl => FullUrl.Length > 60 ? $"{FullUrl[..57]}..." : FullUrl;

private string CurlCommand
{
get
{
var command = $"curl -X {TriggerInput.Method} \"{FullUrl}\"";

var requiredParams = TriggerInput.Parameters.Where(p => p.Value.Required);

// Add query parameters if GET request
if (TriggerInput.Method == "GET" && requiredParams.Any())
{
var queryParams = requiredParams
.Select(p => $"{p.Key}={HttpUtility.UrlEncode($"example {p.Key}")}");
command += $"?{string.Join("&", queryParams)}";
}

// Add headers and body for POST/PUT
if (TriggerInput.Method is "POST" or "PUT" && requiredParams.Any())
{
command += " \\\n -H \"Content-Type: application/json\"";

// Add example body with required parameters
var exampleBody = requiredParams
.ToDictionary(
p => p.Key,
p => $"example {p.Key}"
);

var jsonBody = System.Text.Json.JsonSerializer.Serialize(exampleBody,
new System.Text.Json.JsonSerializerOptions {
WriteIndented = true,
PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase
});
command += $" \\\n -d '{jsonBody}'";
}

return command;
}
}

private string JsonSchema
{
get
{
var schema = new
{
type = "object",
required = TriggerInput.Parameters
.Where(p => p.Value.Required)
.Select(p => p.Key)
.ToList(),
properties = TriggerInput.Parameters.ToDictionary(
p => p.Key,
p => new
{
type = p.Value.Type.ToString().ToLower(),
description = p.Value.Description ?? $"Parameter: {p.Key}",
required = p.Value.Required
}
)
};

return System.Text.Json.JsonSerializer.Serialize(schema,
new System.Text.Json.JsonSerializerOptions {
WriteIndented = true,
PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase
});
}
}

private string TruncatedJsonSchema
{
get
{
var fullSchema = JsonSchema;
if (fullSchema.Length <= 300) return fullSchema;
return fullSchema[..300] + "\n ...\n}";
}
}
private async Task CopyToClipboard(string text)
{
await ClipboardService.CopyTextToClipboard(text);
showCopiedMessage = true;
await InvokeAsync(async () =>
{
await Task.Delay(2000);
showCopiedMessage = false;
StateHasChanged();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Triggers
@using Action = Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Actions.Action

<div class="h-full w-full p-4">
<div class="h-full w-full bg-white p-4 rounded-lg shadow-md">
<div class="flex flex-col items-center">
@if (showToast)
{
Expand Down
47 changes: 32 additions & 15 deletions Blocktrust.CredentialWorkflow.Web/Components/Pages/Designer.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
@using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow
@using Blocktrust.CredentialWorkflow.Web.Components.Features
@using Blocktrust.CredentialWorkflow.Web.Components.Features.PropertyWindow
@using Blocktrust.CredentialWorkflow.Web.Components.Features.HttpEndpointInfo

@using Blocktrust.CredentialWorkflow.Web.Components.Layout
@using Blocktrust.CredentialWorkflow.Web.Services
@using MediatR
Expand All @@ -12,6 +14,7 @@
@using Blocktrust.CredentialWorkflow.Core.Domain.Enums
@using Blocktrust.CredentialWorkflow.Core.Domain.ProcessFlow.Triggers
@using Microsoft.AspNetCore.Authorization

@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IMediator Mediator
Expand All @@ -28,7 +31,7 @@

@if (AppStateService.IsInitialized)
{
<div class="flex flex-col h-screen">
<div class="min-h-screen">
<!-- Top bar -->
<div class="bg-gray-100 p-4 flex items-center justify-end flex-row border-b-2 border-slate-200">
@if (currentWorkflow is not null)
Expand All @@ -50,8 +53,9 @@
@bind:event="oninput"
@onkeypress="HandleKeyPress"/>
<button
class="bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-md transition duration-300 ease-in-out flex items-center ml-4 text-base"
@onclick="SaveName">Save
class="bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-md transition duration-300 ease-in-out flex items-center ml-4 text-base"
@onclick="SaveName">
Save
</button>
}
</div>
Expand Down Expand Up @@ -108,25 +112,39 @@
}

<!-- Main content area -->
<div class="flex-grow flex flex-row">
<div class="flex flex-row">
<!-- Left Panel - HTTP Endpoint Info -->
@if (currentWorkflow?.ProcessFlow?.Triggers.Any() == true &&
currentWorkflow.ProcessFlow.Triggers.First().Value.Type == ETriggerType.HttpRequest)
{
<div class="w-1/4 bg-gray-100 p-4 border-r border-gray-200">
<HttpEndpointInfo
WorkflowId="@workflowId"
TriggerInput="@((TriggerInputHttpRequest)currentWorkflow.ProcessFlow.Triggers.First().Value.Input)" />
</div>
}

<!-- Workflow Designer Area -->
<div class="flex-grow bg-white p-4">
@if (showToast)
{
<div
class="fixed top-4 right-4 bg-slate-800 text-white px-4 py-2 rounded-lg shadow-lg transition-opacity duration-500 @(showToast ? "opacity-100" : "opacity-0")">
<div class="fixed top-4 right-4 bg-slate-800 text-white px-4 py-2 rounded-lg shadow-lg transition-opacity duration-500 @(showToast ? "opacity-100" : "opacity-0")">
@toastMessage
</div>
}
<WorkflowDesigner @ref="workflowDesigner"
Workflow="@currentWorkflow"
OnItemSelected="HandleItemSelected"
OnChange="HandleChange"/>
Workflow="@currentWorkflow"
OnItemSelected="HandleItemSelected"
OnChange="HandleChange"/>
</div>
<div class="bg-gray-200 p-4 w-1/3">
<PropertyWindow SelectedItem="@selectedItem"
OnItemCreated="HandleItemCreated"
OnChange="HandleChange"
FlowItems="@flowItems"/>

<!-- Right Panel - Property Window -->
<div class="w-1/3 bg-gray-200 p-4">
<PropertyWindow
SelectedItem="@selectedItem"
OnItemCreated="HandleItemCreated"
OnChange="HandleChange"
FlowItems="@flowItems"/>
</div>
</div>
</div>
Expand All @@ -137,7 +155,6 @@ else
<div class="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-slate-900"></div>
</div>
}

@code {
[Parameter] public Guid workflowId { get; set; }
private readonly CancellationTokenSource cts = new();
Expand Down
23 changes: 23 additions & 0 deletions Blocktrust.CredentialWorkflow.Web/wwwroot/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,10 @@ video {
border-color: rgb(226 232 240 / var(--tw-divide-opacity));
}

.overflow-auto {
overflow: auto;
}

.overflow-hidden {
overflow: hidden;
}
Expand Down Expand Up @@ -1177,6 +1181,10 @@ video {
border-top-width: 2px;
}

.border-r {
border-right-width: 1px;
}

.border-blue-500 {
--tw-border-opacity: 1;
border-color: rgb(59 130 246 / var(--tw-border-opacity));
Expand Down Expand Up @@ -1357,6 +1365,11 @@ video {
background-color: rgb(254 249 195 / var(--tw-bg-opacity));
}

.bg-green-50 {
--tw-bg-opacity: 1;
background-color: rgb(240 253 244 / var(--tw-bg-opacity));
}

.bg-opacity-50 {
--tw-bg-opacity: 0.5;
}
Expand Down Expand Up @@ -1875,6 +1888,11 @@ a {
background-color: rgb(71 85 105 / var(--tw-bg-opacity));
}

.hover\:bg-gray-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
}

.hover\:text-blue-700:hover {
--tw-text-opacity: 1;
color: rgb(29 78 216 / var(--tw-text-opacity));
Expand Down Expand Up @@ -1925,6 +1943,11 @@ a {
color: rgb(51 65 85 / var(--tw-text-opacity));
}

.hover\:text-gray-700:hover {
--tw-text-opacity: 1;
color: rgb(55 65 81 / var(--tw-text-opacity));
}

.hover\:opacity-80:hover {
opacity: 0.8;
}
Expand Down