Skip to content

Commit dc12d05

Browse files
committed
Support richer plugin metadata and enhance UI
Updated the plugin metadata structure to include `Specifications` and `Operations`, serialized as JSON. Replaced `manifest.json` with `metadata.json` across the application. Enhanced the UI with a tabbed interface for installation instructions and introduced a reusable `CodeBlock` component with copy-to-clipboard functionality. Removed the old `CodeCopy` component. Upgraded the target framework to `net10.0` across all projects. Updated `PluginVersionEntity` to replace `Manifest` with `MetadataFile`. Adjusted styles and removed unused CSS classes. #48
1 parent 97b0fc6 commit dc12d05

16 files changed

Lines changed: 134 additions & 65 deletions

File tree

src/FlowSynx.PluginRegistry.Application/Features/Plugins/Query/PluginDetails/PluginDetailsHandler.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using FlowSynx.PluginRegistry.Domain.Plugin;
33
using MediatR;
44
using Microsoft.Extensions.Logging;
5+
using System.Text.Json;
56

67
namespace FlowSynx.PluginRegistry.Application.Features.Plugins.Query.PluginDetails;
78

@@ -52,7 +53,9 @@ public async Task<Result<PluginDetailsResponse>> Handle(PluginDetailsRequest req
5253
Versions = plugin.Plugin.Versions
5354
.OrderByDescending(x=>x.LastModifiedOn)
5455
.ThenByDescending(x=>x.CreatedOn)
55-
.Select(x=>x.Version)
56+
.Select(x=>x.Version),
57+
Specifications = JsonSerializer.Deserialize<object>(plugin.Specifications ?? ""),
58+
Operations = JsonSerializer.Deserialize<object>(plugin.Operations ?? "")
5659
};
5760

5861
return await Result<PluginDetailsResponse>.SuccessAsync(response);

src/FlowSynx.PluginRegistry.Application/Features/Plugins/Query/PluginDetails/PluginDetailsResponse.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class PluginDetailsResponse
1414
public string? CategoryTitle { get; set; }
1515
public required string MinimumFlowSynxVersion { get; set; }
1616
public string? TargetFlowSynxVersion { get; set; }
17+
public object? Specifications { get; set; }
18+
public object? Operations { get; set; }
1719
public DateTime LastUpdated { get; set; }
1820
public int TotalDownload { get; set; } = 0;
1921
public bool IsTrusted { get; set; } = false;

src/FlowSynx.PluginRegistry.Application/FlowSynx.PluginRegistry.Application.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net9.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>

src/FlowSynx.PluginRegistry.Domain/FlowSynx.PluginRegistry.Domain.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net9.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>

src/FlowSynx.PluginRegistry.Domain/Plugin/PluginVersionEntity.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ public class PluginVersionEntity : AuditableEntity<Guid>, ISoftDeletable
2020
public required Guid PluginCategoryId { get; set; }
2121
public required string MinimumFlowSynxVersion { get; set; }
2222
public string? TargetFlowSynxVersion { get; set; }
23+
public string? Specifications { get; set; }
24+
public string? Operations { get; set; }
2325
public bool? IsLatest { get; set; }
24-
public string? Manifest { get; set; }
26+
public string? MetadataFile { get; set; }
2527
public string? Checksum { get; set; }
2628
public bool IsActive { get; set; } = true;
2729
public bool IsDeleted { get; set; } = false;

src/FlowSynx.PluginRegistry.Infrastructure/Configurations/PluginVersionEntityConfiguration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void Configure(EntityTypeBuilder<PluginVersionEntity> builder)
2323
.HasMaxLength(50)
2424
.IsRequired();
2525

26-
builder.Property(v => v.Manifest)
26+
builder.Property(v => v.MetadataFile)
2727
.HasMaxLength(4096);
2828

2929
builder.Property(t => t.PluginLocation)

src/FlowSynx.PluginRegistry.Infrastructure/FlowSynx.PluginRegistry.Infrastructure.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net9.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
</PropertyGroup>

src/FlowSynx.Pluginregistry/Components/Pages/Manage/Upload.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<strong>Package Requirements</strong>
4343
<ul class="mb-0 mt-2 small">
4444
<li>Valid <b class="text-primary">.fspack</b> archive format</li>
45-
<li>Include a <b class="text-primary">manifest.json</b> manifest with plugin metadata</li>
45+
<li>Include a <b class="text-primary">metadata.json</b> file with plugin metadata</li>
4646
<li>All necessary plugin files and dependencies</li>
4747
</ul>
4848
</div>

src/FlowSynx.Pluginregistry/Components/Pages/Plugins/PluginsDetails.razor

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
@using FlowSynx.Pluginregistry.Services
99
@using FlowSynx.Pluginregistry.Components.Shared;
1010
@using Microsoft.AspNetCore.Components.Authorization
11+
@using Microsoft.JSInterop
1112

1213
@inject NavigationManager Navigation
1314
@inject IStatsApiService Stats
@@ -165,16 +166,48 @@
165166
</div>
166167
}
167168

168-
<!-- Installation Code -->
169+
<!-- Installation Tabs with Active Tab Copy Button -->
169170
<div class="card border shadow-sm mb-4">
170171
<div class="card-body p-4">
172+
<!-- Header with inline Copy button -->
171173
<div class="d-flex justify-content-between align-items-center mb-3">
172174
<h5 class="mb-0 fw-bold">
173-
<i class="bi bi-code-square me-2 text-primary"></i>Installation
175+
<i class="bi bi-code-square me-2 text-primary"></i>
176+
Installation
174177
</h5>
175-
<CodeCopy CodeToCopy="@jsonCodeBlock" />
176178
</div>
177-
<pre class="plugin-code-block p-3 rounded-3 mb-0"><code class="language-json">@jsonCodeBlock</code></pre>
179+
180+
<!-- Tabs -->
181+
<ul class="nav nav-tabs" role="tablist">
182+
<li class="nav-item">
183+
<button class="nav-link @(ActiveTab == "flowsynx-manager" ? "active" : "")"
184+
@onclick='() => ActiveTab = "flowsynx-manager"'>
185+
FlowSynx Manager
186+
</button>
187+
</li>
188+
<li class="nav-item">
189+
<button class="nav-link @(ActiveTab == "flowctl-cli" ? "active" : "")"
190+
@onclick='() => ActiveTab = "flowctl-cli"'>
191+
FlowCtl CLI
192+
</button>
193+
</li>
194+
</ul>
195+
196+
<!-- Tab Content -->
197+
<div class="tab-content p-0 border border-top-0 rounded-bottom">
198+
@if (ActiveTab == "flowsynx-manager")
199+
{
200+
<div class="tab-pane fade show active">
201+
<CodeBlock Code="@flowSynxCode" />
202+
</div>
203+
}
204+
else if (ActiveTab == "flowctl-cli")
205+
{
206+
<div class="tab-pane fade show active">
207+
<CodeBlock Code="@flowctlCode" />
208+
</div>
209+
}
210+
</div>
178211
</div>
179212
</div>
180213

@@ -369,17 +402,16 @@
369402
</div>
370403

371404
@code {
405+
[Inject] private IJSRuntime JS { get; set; }
406+
372407
[Parameter]
373408
public string Type { get; set; } = "";
374409

375410
[Parameter]
376411
public string Version { get; set; } = "";
377412

378-
private string jsonCodeBlock => JsonSerializer.Serialize(new
379-
{
380-
Type,
381-
Version
382-
}, new JsonSerializerOptions { WriteIndented = true });
413+
private string flowSynxCode => $"{Type}:{Version}";
414+
private string flowctlCode => $"flowctl plugins install \"{Type}:{Version}\"";
383415

384416
Result<PluginDetailsResponse>? plugin;
385417
private bool isOwner = false;
@@ -388,6 +420,8 @@
388420
private bool statusSuccess = false;
389421
private string? currentUsername;
390422

423+
private string ActiveTab { get; set; } = "flowsynx-manager";
424+
391425
protected override async Task OnInitializedAsync()
392426
{
393427
plugin = await Stats.GetPluginDetails(Type, Version);
@@ -407,6 +441,18 @@
407441
}
408442
}
409443

444+
private async Task CopyActiveTabCode()
445+
{
446+
string codeToCopy = ActiveTab switch
447+
{
448+
"flowsynx-manager" => flowSynxCode,
449+
"flowctl-cli" => flowctlCode,
450+
_ => ""
451+
};
452+
453+
await JS.InvokeVoidAsync("navigator.clipboard.writeText", codeToCopy);
454+
}
455+
410456
private async Task EnableVersion()
411457
{
412458
isProcessing = true;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@using Microsoft.JSInterop
2+
@inject IJSRuntime JS
3+
4+
<div class="position-relative">
5+
<pre class="bg-light p-3 rounded mb-0 fw-bold"><code>@Code</code></pre>
6+
<button class="btn btn-sm btn-outline-secondary border border-secondary-subtle position-absolute top-0 end-0 m-2"
7+
@onclick="CopyCode">
8+
<i class="bi bi-clipboard"></i>
9+
</button>
10+
</div>
11+
12+
@code {
13+
[Parameter] public string Code { get; set; } = string.Empty;
14+
15+
private async Task CopyCode()
16+
{
17+
await JS.InvokeVoidAsync("navigator.clipboard.writeText", Code);
18+
}
19+
}

0 commit comments

Comments
 (0)