Skip to content

Commit d32d2fb

Browse files
Use # Navigation on website
1 parent d929cea commit d32d2fb

File tree

5 files changed

+185
-235
lines changed

5 files changed

+185
-235
lines changed

.github/workflows/deploy-lql-website.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,10 @@ jobs:
4545
- name: Publish Blazor WebAssembly project
4646
run: dotnet publish ./Lql/Website/LqlWebsite.csproj -c Release -o release --nologo
4747

48-
- name: Copy index.html to 404.html for GitHub Pages SPA routing
49-
run: cp release/wwwroot/index.html release/wwwroot/404.html
50-
5148
- name: Update base href for GitHub Pages
5249
run: |
5350
REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f2)
5451
sed -i 's/<base href="\/" \/>/<base href="\/'$REPO_NAME'\/" \/>/g' release/wwwroot/index.html
55-
sed -i 's/<base href="\/" \/>/<base href="\/'$REPO_NAME'\/" \/>/g' release/wwwroot/404.html
5652
5753
- name: Add .nojekyll file
5854
run: touch release/wwwroot/.nojekyll
Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
@inherits LayoutComponentBase
2-
@inject NavigationManager Navigation
32

43
<div class="page">
54
<header>
65
<div class="container">
76
<div class="header-content">
8-
<div class="logo" @onclick="NavigateToHome" style="cursor: pointer;">
7+
<div class="logo">
98
<img src="lql-icon.png" alt="LQL Logo">
109
<span class="logo-text">LQL</span>
1110
</div>
1211
<nav>
1312
<ul>
14-
<li><a href="@Navigation.BaseUri" @onclick="NavigateToHome" @onclick:preventDefault="true">Home</a></li>
15-
<li><a href="@(Navigation.BaseUri)playground" @onclick="NavigateToPlayground" @onclick:preventDefault="true">Playground</a></li>
13+
<li><a href="#features">Features</a></li>
14+
<li><a href="#examples">Examples</a></li>
15+
<li><a href="#playground">Playground</a></li>
1616
<li><a href="https://github.com/MelbourneDeveloper/DataProvider" target="_blank">GitHub</a></li>
1717
</ul>
1818
</nav>
@@ -22,16 +22,4 @@
2222
<main>
2323
@Body
2424
</main>
25-
</div>
26-
27-
@code {
28-
private void NavigateToHome()
29-
{
30-
Navigation.NavigateTo("/");
31-
}
32-
33-
private void NavigateToPlayground()
34-
{
35-
Navigation.NavigateTo("/playground");
36-
}
37-
}
25+
</div>

Lql/Website/Components/Pages/Home.razor

Lines changed: 180 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
@page "/"
22
@using Microsoft.AspNetCore.Components.Web
3-
@inject NavigationManager Navigation
3+
@using Lql
4+
@using Lql.Postgres
5+
@using Lql.SqlServer
6+
@using Results
47

58
<PageTitle>Lambda Query Language (LQL) - Functional Data Querying</PageTitle>
69

@@ -12,7 +15,7 @@
1215

1316
<div class="cta-buttons">
1417
<a href="#examples" class="btn btn-primary">See Examples</a>
15-
<button @onclick="NavigateToPlayground" class="btn btn-secondary">Try Playground</button>
18+
<a href="#playground" class="btn btn-secondary">Try Playground</a>
1619
</div>
1720

1821
<div class="hero-code">
@@ -201,6 +204,65 @@
201204
</div>
202205
</section>
203206

207+
<section id="playground" class="playground">
208+
<div class="container">
209+
<div class="section-header">
210+
<h2>LQL Playground</h2>
211+
<p>Try Lambda Query Language and see how it transpiles to PostgreSQL or SQL Server</p>
212+
</div>
213+
214+
<div class="playground-content">
215+
<div class="input-section">
216+
<h3 class="section-title">LQL Input</h3>
217+
<div class="controls">
218+
<select @bind="selectedDialect" class="dialect-selector">
219+
<option value="PostgreSQL">PostgreSQL</option>
220+
<option value="SqlServer">SQL Server</option>
221+
</select>
222+
<button @onclick="ConvertLql" class="convert-btn" disabled="@isConverting">
223+
@if (isConverting)
224+
{
225+
<text>Converting...</text>
226+
}
227+
else
228+
{
229+
<text>Convert to SQL</text>
230+
}
231+
</button>
232+
</div>
233+
<textarea @bind="lqlInput" @bind:event="oninput" class="lql-input"
234+
placeholder="Enter your LQL query here...
235+
236+
Example:
237+
users |> select(users.id, users.name, users.email)"></textarea>
238+
</div>
239+
240+
<div class="output-section">
241+
<h3 class="section-title">@selectedDialect Output</h3>
242+
<div class="sql-output">@sqlOutput</div>
243+
@if (!string.IsNullOrEmpty(errorMessage))
244+
{
245+
<div class="error-message">
246+
<strong>Error:</strong> @errorMessage
247+
</div>
248+
}
249+
</div>
250+
</div>
251+
252+
<div class="examples-section">
253+
<h3 class="section-title">Example Queries</h3>
254+
<p style="color: var(--text-secondary); margin-bottom: 16px;">Click any example to load it into the editor:</p>
255+
<div class="example-buttons">
256+
<button @onclick="() => LoadExample(simpleSelectExample)" class="example-btn">Simple Select</button>
257+
<button @onclick="() => LoadExample(joinExample)" class="example-btn">Join Tables</button>
258+
<button @onclick="() => LoadExample(filterExample)" class="example-btn">Filter Data</button>
259+
<button @onclick="() => LoadExample(aggregateExample)" class="example-btn">Aggregation</button>
260+
<button @onclick="() => LoadExample(complexExample)" class="example-btn">Complex Query</button>
261+
</div>
262+
</div>
263+
</div>
264+
</section>
265+
204266
<footer>
205267
<div class="container">
206268
<div class="footer-content">
@@ -216,8 +278,122 @@
216278
</footer>
217279

218280
@code {
219-
private void NavigateToPlayground()
281+
private string lqlInput = "";
282+
private string sqlOutput = "Enter LQL code and click 'Convert to SQL' to see the result.";
283+
private string errorMessage = "";
284+
private string selectedDialect = "PostgreSQL";
285+
private bool isConverting = false;
286+
287+
// Example queries
288+
private readonly string simpleSelectExample = "users |> select(users.id, users.name, users.email)";
289+
290+
private readonly string joinExample = @"users
291+
|> join(orders, on = users.id = orders.user_id)
292+
|> select(users.name, orders.total, orders.status)";
293+
294+
private readonly string filterExample = @"employees
295+
|> select(employees.id, employees.name, employees.salary)
296+
|> filter(fn(row) => row.employees.salary > 50000 and row.employees.department = 'Engineering')";
297+
298+
private readonly string aggregateExample = @"orders
299+
|> group_by(orders.user_id)
300+
|> select(
301+
orders.user_id,
302+
count(*) as order_count,
303+
sum(orders.total) as total_amount,
304+
avg(orders.total) as avg_amount
305+
)
306+
|> having(fn(group) => count(*) > 2)
307+
|> order_by(total_amount desc)";
308+
309+
private readonly string complexExample = @"-- Complex analytics query
310+
let joined =
311+
users
312+
|> join(orders, on = users.id = orders.user_id)
313+
|> filter(fn(row) => row.orders.status = 'completed')
314+
315+
joined
316+
|> group_by(users.id)
317+
|> select(
318+
users.name,
319+
count(*) as total_orders,
320+
sum(orders.total) as revenue,
321+
avg(orders.total) as avg_order_value
322+
)
323+
|> filter(fn(row) => row.revenue > 1000)
324+
|> order_by(revenue desc)
325+
|> limit(10)";
326+
327+
private async Task ConvertLql()
328+
{
329+
if (string.IsNullOrWhiteSpace(lqlInput))
330+
{
331+
errorMessage = "Please enter some LQL code to convert.";
332+
sqlOutput = "";
333+
return;
334+
}
335+
336+
isConverting = true;
337+
errorMessage = "";
338+
sqlOutput = "Converting...";
339+
340+
try
341+
{
342+
await Task.Delay(100); // Small delay to show loading state
343+
344+
// Parse the LQL code
345+
var statementResult = LqlStatementConverter.ToStatement(lqlInput);
346+
347+
if (statementResult is Result<LqlStatement, SqlError>.Failure parseFailure)
348+
{
349+
errorMessage = parseFailure.ErrorValue.DetailedMessage ?? parseFailure.ErrorValue.Message;
350+
sqlOutput = "";
351+
return;
352+
}
353+
354+
var statement = ((Result<LqlStatement, SqlError>.Success)statementResult).Value;
355+
356+
// Convert to the selected SQL dialect
357+
Result<string, SqlError> sqlResult = selectedDialect switch
358+
{
359+
"PostgreSQL" => statement.ToPostgreSql(),
360+
"SqlServer" => statement.ToSqlServer(),
361+
_ => new Result<string, SqlError>.Failure(new SqlError($"Unsupported dialect: {selectedDialect}"))
362+
};
363+
364+
if (sqlResult is Result<string, SqlError>.Failure sqlFailure)
365+
{
366+
errorMessage = sqlFailure.ErrorValue.DetailedMessage ?? sqlFailure.ErrorValue.Message;
367+
sqlOutput = "";
368+
return;
369+
}
370+
371+
var sql = ((Result<string, SqlError>.Success)sqlResult).Value;
372+
sqlOutput = sql;
373+
errorMessage = "";
374+
}
375+
catch (Exception ex)
376+
{
377+
errorMessage = $"An unexpected error occurred: {ex}";
378+
sqlOutput = "";
379+
}
380+
finally
381+
{
382+
isConverting = false;
383+
}
384+
}
385+
386+
private void LoadExample(string example)
387+
{
388+
lqlInput = example;
389+
errorMessage = "";
390+
sqlOutput = "Click 'Convert to SQL' to see the result.";
391+
}
392+
393+
protected override async Task OnInitializedAsync()
220394
{
221-
Navigation.NavigateTo("/playground");
395+
// Load a simple example by default
396+
lqlInput = simpleSelectExample;
397+
await ConvertLql();
222398
}
223399
}

0 commit comments

Comments
 (0)