Skip to content

Commit a441454

Browse files
authored
feature/api landing page (#1557)
* API landing page now contains a listing of all API's for ease of reference * simplify navigation if using tag groups * lint and only reload API on debug
1 parent 333d0c5 commit a441454

File tree

7 files changed

+242
-93
lines changed

7 files changed

+242
-93
lines changed

src/Elastic.ApiExplorer/Landing/LandingNavigationItem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public LandingNavigationItem(string url)
5252
}
5353

5454
/// <inheritdoc />
55-
public bool IsUsingNavigationDropdown => NavigationItems.OfType<ClassificationNavigationItem>().Any();
55+
public bool IsUsingNavigationDropdown => false;
5656
}
5757

5858
public interface IApiGroupingNavigationItem<out TGroupingModel, out TNavigationItem> : INodeNavigationItem<TGroupingModel, TNavigationItem>
@@ -106,7 +106,7 @@ public class ClassificationNavigationItem(ApiClassification classification, Land
106106
public override string Id { get; } = ShortId.Create(classification.Name);
107107

108108
/// <inheritdoc />
109-
public bool IsUsingNavigationDropdown => true;
109+
public bool IsUsingNavigationDropdown => false;
110110
}
111111

112112
public class TagNavigationItem(ApiTag tag, IRootNavigationItem<IApiGroupingModel, INavigationItem> rootNavigation, INodeNavigationItem<INavigationModel, INavigationItem> parent)
Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,92 @@
11
@inherits RazorSliceHttpResult<Elastic.ApiExplorer.Landing.LandingViewModel>
2+
@using Elastic.ApiExplorer.Landing
3+
@using Elastic.ApiExplorer.Operations
4+
@using Elastic.Documentation.Site.Navigation
25
@implements IUsesLayout<Elastic.ApiExplorer._Layout, GlobalLayoutViewModel>
36
@functions {
47
public GlobalLayoutViewModel LayoutModel => Model.CreateGlobalLayoutModel();
8+
9+
private IHtmlContent RenderOp(IReadOnlyCollection<OperationNavigationItem> endpointOperations)
10+
{
11+
<ul class="api-url-listing">
12+
@foreach (var overload in endpointOperations)
13+
{
14+
var method = overload.Model.OperationType.ToString().ToLowerInvariant();
15+
<li class="api-url-list-item">
16+
<a href="@overload.Url" class="current api-url-list-item-landing" hx-disable="true">
17+
<span class="api-method api-method-@method">@method.ToUpperInvariant()</span>
18+
<span class="api-url">@overload.Model.Route</span>
19+
</a>
20+
</li>
21+
}
22+
</ul>
23+
24+
return HtmlString.Empty;
25+
}
26+
27+
private IHtmlContent RenderProduct(INavigationItem item)
28+
{
29+
if (item is INodeNavigationItem<INavigationModel, INavigationItem> node)
30+
{
31+
foreach (var navigationItem in node.NavigationItems)
32+
{
33+
if (navigationItem is ClassificationNavigationItem classification)
34+
{
35+
<tr>
36+
<td colspan="2"><h2>@(classification.NavigationTitle)</h2></td>
37+
</tr>
38+
@RenderProduct(classification)
39+
}
40+
else if (navigationItem is TagNavigationItem tag)
41+
{
42+
<tr>
43+
<td colspan="2"><h3>@(tag.NavigationTitle)</h3><td>
44+
</tr>
45+
@RenderProduct(tag)
46+
}
47+
else if (navigationItem is EndpointNavigationItem endpoint)
48+
{
49+
var endpointOperations =
50+
endpoint is { NavigationItems.Count: > 0 } && endpoint.NavigationItems.All(n => n.Hidden)
51+
? endpoint.NavigationItems
52+
: [];
53+
if (endpointOperations.Count > 0)
54+
{
55+
<tr>
56+
<td class="api-name">@(endpoint.NavigationTitle)</td>
57+
<td>@RenderOp(endpointOperations)</td>
58+
</tr>
59+
}
60+
else
61+
{
62+
@RenderProduct(endpoint)
63+
}
64+
}
65+
else if (navigationItem is OperationNavigationItem operation)
66+
{
67+
<tr>
68+
<td class="api-name">@(operation.NavigationTitle)</td>
69+
<td>@RenderOp([operation])</td>
70+
</tr>
71+
}
72+
else
73+
{
74+
throw new Exception($"Unexpected type: {item.GetType().FullName}");
75+
}
76+
}
77+
}
78+
79+
return HtmlString.Empty;
80+
81+
}
582
}
683
<section id="elastic-docs-v3">
784
<h1>@Model.ApiInfo.Title</h1>
8-
<p>@Model.ApiInfo.Description</p>
9-
<p>License: @Model.ApiInfo.License?.Identifier</p>
85+
<p>@Model.RenderMarkdown(Model.ApiInfo.Description)</p>
86+
<p>License: @Model.ApiInfo.License?.Name</p>
87+
<div class="api-overview">
88+
<table>
89+
@RenderProduct(Model.CurrentNavigationItem.NavigationRoot)
90+
</table>
91+
</div>
1092
</section>

src/Elastic.ApiExplorer/Operations/OperationView.cshtml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
public GlobalLayoutViewModel LayoutModel => Model.CreateGlobalLayoutModel();
88
}
99
@{
10-
var parent = Model.CurrentNavigationItem.Parent as EndpointNavigationItem;
1110
var self = Model.CurrentNavigationItem as OperationNavigationItem;
1211
var allOperations =
13-
parent is not null && parent.NavigationItems.Count > 0 && parent.NavigationItems.All(n => n.Hidden)
12+
Model.CurrentNavigationItem.Parent is EndpointNavigationItem { NavigationItems.Count: > 0 } parent && parent.NavigationItems.All(n => n.Hidden)
1413
? parent.NavigationItems
1514
: self is not null
1615
? [self]
@@ -87,4 +86,4 @@
8786
<aside>
8887

8988
</aside>
90-
</div>
89+
</div>

src/Elastic.Documentation.Site/Assets/api-docs.css

Lines changed: 104 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
@apply border-grey-30 text-grey-120 bg-white;
4343
font-weight: bold;
4444
}
45+
a.api-url-list-item-landing {
46+
font-weight: normal !important;
47+
}
48+
a.api-url-list-item-landing:hover {
49+
font-weight: normal !important;
50+
}
4551
}
4652
li:only-child {
4753
a.current {
@@ -51,53 +57,108 @@
5157
@apply border-grey-20 bg-white;
5258
}
5359
}
54-
.api-method {
55-
@apply rounded-sm border;
56-
padding-left: var(--spacing);
57-
padding-right: var(--spacing);
58-
font-family: var(
59-
--default-mono-font-family,
60-
ui-monospace,
61-
SFMono-Regular,
62-
Menlo,
63-
Monaco,
64-
Consolas,
65-
'Liberation Mono',
66-
'Courier New',
67-
monospace
68-
);
69-
font-feature-settings: var(
70-
--default-mono-font-feature-settings,
71-
normal
72-
);
73-
font-variation-settings: var(
74-
--default-mono-font-variation-settings,
75-
normal
76-
);
77-
font-size: 0.8em;
78-
display: inline-block;
79-
font-weight: bold;
80-
}
81-
.api-method-get {
82-
@apply border-blue-elastic-30 bg-blue-elastic-10 text-blue-elastic;
83-
}
84-
.api-method-put {
85-
@apply border-yellow-30 bg-yellow-10 text-yellow-90;
86-
}
87-
.api-method-post {
88-
@apply border-green-30 bg-green-10 text-green-90;
89-
}
90-
.api-method-delete {
91-
@apply border-red-30 bg-red-10 text-red-90;
92-
}
93-
.api-url {
94-
margin-left: calc(var(--spacing) * 2);
95-
display: inline-block;
96-
}
9760
.api-url-list-item {
9861
@apply mt-4;
9962
}
10063
}
64+
.api-overview {
65+
.api-url-listing {
66+
@apply mt-1;
67+
}
68+
.api-url-list-item {
69+
@apply mt-1;
70+
}
71+
li {
72+
a {
73+
@apply text-grey-80 inline-block w-full p-2 pr-2 pl-2 no-underline;
74+
@apply rounded-sm border border-white;
75+
}
76+
a:hover {
77+
@apply bg-grey-10;
78+
@apply border-grey-20;
79+
}
80+
a.current {
81+
@apply text-grey-80 inline-block w-full p-2 pr-2 pl-2 no-underline;
82+
@apply rounded-sm border border-white;
83+
}
84+
a.current:hover {
85+
@apply bg-grey-10;
86+
@apply border-grey-20;
87+
}
88+
}
89+
li:only-child {
90+
a.current {
91+
@apply text-grey-80 inline-block w-full p-2 pr-2 pl-2 no-underline;
92+
@apply rounded-sm border border-white;
93+
}
94+
a.current:hover {
95+
@apply bg-grey-10;
96+
}
97+
}
98+
table {
99+
td {
100+
text-align: left;
101+
vertical-align: top;
102+
}
103+
td:has(h2) {
104+
}
105+
td:has(h3) {
106+
@apply border-b-grey-20 mb-2 border-b-1 pb-2;
107+
}
108+
td.api-name {
109+
@apply pr-2;
110+
text-align: left;
111+
font-weight: bold;
112+
}
113+
tr:has(td.api-name) {
114+
@apply border-b-grey-10 border-b-1;
115+
}
116+
tr:has(td.api-name) td {
117+
@apply mt-4 mb-4 pt-4 pb-4;
118+
}
119+
}
120+
}
121+
122+
.api-method {
123+
@apply rounded-sm border;
124+
padding-left: var(--spacing);
125+
padding-right: var(--spacing);
126+
font-family: var(
127+
--default-mono-font-family,
128+
ui-monospace,
129+
SFMono-Regular,
130+
Menlo,
131+
Monaco,
132+
Consolas,
133+
'Liberation Mono',
134+
'Courier New',
135+
monospace
136+
);
137+
font-feature-settings: var(--default-mono-font-feature-settings, normal);
138+
font-variation-settings: var(
139+
--default-mono-font-variation-settings,
140+
normal
141+
);
142+
font-size: 0.8em;
143+
display: inline-block;
144+
font-weight: bold;
145+
}
146+
.api-method-get {
147+
@apply border-blue-elastic-30 bg-blue-elastic-10 text-blue-elastic;
148+
}
149+
.api-method-put {
150+
@apply border-yellow-30 bg-yellow-10 text-yellow-90;
151+
}
152+
.api-method-post {
153+
@apply border-green-30 bg-green-10 text-green-90;
154+
}
155+
.api-method-delete {
156+
@apply border-red-30 bg-red-10 text-red-90;
157+
}
158+
.api-url {
159+
margin-left: calc(var(--spacing) * 2);
160+
display: inline-block;
161+
}
101162
#elastic-api-v3 {
102163
dt a {
103164
@apply no-underline;

0 commit comments

Comments
 (0)