Forge
csharp3407750f
1using AgentForge.Abstractions;
2using AgentForge.Contracts;
3using AgentForge.Plugin.View.Components;
4
5namespace AgentForge.Plugin.View.Pages;
6
7internal static class ForgeHomePage
8{
9 internal static string Render(
10 IReadOnlyList<RepoResponse> repos,
11 ForgeOrgCatalogViewContext? groupingContext = null,
12 IForgeOrgCatalogGrouping? grouping = null,
13 IForgeMainPageCatalogBody? mainPageBody = null,
14 IReadOnlyList<ForgeOrgCatalogRepoItem>? catalogItems = null)
15 {
16 return ForgeHtml.Fragment(
17 ForgeViewLogo.Render(),
18 ForgeViewTitle.Render("Agent Forge"),
19 ForgeViewSubtitle.Render("View layer (read + MR approve). Create issues/MR via MCP or CIDE."),
20 ForgeViewRepositoryPicker.Render(repos),
21 ForgeViewSectionHeading.Render("Catalog"),
22 RenderCatalog(repos, groupingContext, grouping, mainPageBody, catalogItems),
23 ForgeViewAuthLinks.Render());
24 }
25
26 private static string RenderCatalog(
27 IReadOnlyList<RepoResponse> repos,
28 ForgeOrgCatalogViewContext? groupingContext,
29 IForgeOrgCatalogGrouping? grouping,
30 IForgeMainPageCatalogBody? mainPageBody,
31 IReadOnlyList<ForgeOrgCatalogRepoItem>? catalogItems)
32 {
33 if (catalogItems is null || groupingContext is null)
34 return ForgeViewRepoCatalog.RenderTable(repos);
35
36 var toolbar = grouping?.RenderToolbar(groupingContext) ?? "";
37 var body = RenderCatalogBody(catalogItems, groupingContext, grouping, mainPageBody);
38 return ForgeHtml.Fragment(toolbar, body);
39 }
40
41 private static string RenderCatalogBody(
42 IReadOnlyList<ForgeOrgCatalogRepoItem> catalogItems,
43 ForgeOrgCatalogViewContext groupingContext,
44 IForgeOrgCatalogGrouping? grouping,
45 IForgeMainPageCatalogBody? mainPageBody)
46 {
47 var hasGroupFilter = !string.IsNullOrWhiteSpace(groupingContext.ActiveGroupPath);
48 var hasGroupStack = groupingContext.GroupStack.Count > 0;
49
50 if (grouping is not null && (hasGroupStack || hasGroupFilter))
51 {
52 var filtered = hasGroupFilter
53 ? FilterItems(catalogItems, groupingContext.ActiveGroupPath!)
54 : catalogItems;
55 return grouping.RenderRepoBody(filtered, groupingContext);
56 }
57
58 if (mainPageBody is not null)
59 return mainPageBody.RenderTree(catalogItems, groupingContext, grouping);
60
61 if (grouping is not null)
62 return grouping.RenderRepoBody(catalogItems, groupingContext);
63
64 return ForgeViewRepoCatalog.RenderTable(
65 catalogItems.Select(item => new RepoResponse(
66 item.Name,
67 item.Name,
68 "",
69 item.DriveMode,
70 "",
71 item.CreatedAt ?? DateTimeOffset.MinValue,
72 item.Group,
73 item.Org,
74 item.Visibility)).ToList());
75 }
76
77 private static IReadOnlyList<ForgeOrgCatalogRepoItem> FilterItems(
78 IReadOnlyList<ForgeOrgCatalogRepoItem> repos,
79 string activeGroupPath) =>
80 repos
81 .Where(repo => !string.IsNullOrWhiteSpace(repo.Group)
82 && (string.Equals(repo.Group, activeGroupPath, StringComparison.OrdinalIgnoreCase)
83 || repo.Group!.StartsWith(activeGroupPath + "/", StringComparison.OrdinalIgnoreCase)))
84 .ToList();
85}
86
View only · write via MCP/CIDE