acalejos commited on
Commit
496129c
1 Parent(s): 0ae9041

Update public-apps/github-repo-report.livemd

Browse files

Use context aware Kino.Control.button instead of Kino.Input.download

Files changed (1) hide show
  1. public-apps/github-repo-report.livemd +68 -50
public-apps/github-repo-report.livemd CHANGED
@@ -385,12 +385,12 @@ defmodule LiveReport do
385
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
386
  </head>
387
  <body>
388
- <button class="relative block w-full rounded-lg border-2 border-dashed border-gray-300 p-12 text-center hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
389
  <svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
390
  <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
391
  </svg>
392
  <span class="mt-2 block text-sm font-semibold text-gray-900">Generate Your Report to See it Here!</span>
393
- </button>
394
  </body>
395
  </html>
396
  """
@@ -407,8 +407,8 @@ defmodule LiveReport do
407
  Kino.JS.Live.call(kino, {:replace, :loading, origin})
408
  end
409
 
410
- def download_html(kino) do
411
- Kino.JS.Live.call(kino, {:download})
412
  end
413
 
414
  defp format_category(category) do
@@ -430,8 +430,9 @@ defmodule LiveReport do
430
  end
431
 
432
  @impl true
433
- def handle_call({:download}, _from, ctx) do
434
- {:reply, ctx.html, nil}
 
435
  end
436
 
437
  def handle_call({:replace, %Report{} = report, origin}, _from, ctx) do
@@ -446,7 +447,7 @@ defmodule LiveReport do
446
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
447
  </head>
448
  <body class="bg-gray-100">
449
- <div class="container mx-auto p-6 mt-10 max-w-4xl">
450
  <div class="bg-white shadow overflow-hidden sm:rounded-lg">
451
  <div class="px-4 py-5 sm:px-6">
452
  <h1 class="text-2xl leading-6 font-medium text-gray-900">Project Report</h1>
@@ -590,9 +591,26 @@ defmodule LiveReport do
590
  ctx.root.innerHTML = html;
591
 
592
  ctx.handleEvent("replace", (html) => {
593
- console.log(html);
594
  ctx.root.innerHTML = html;
595
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
596
  }
597
  """
598
  end
@@ -647,8 +665,6 @@ form =
647
  submit: "Generate"
648
  )
649
 
650
- frame = Kino.Frame.new()
651
-
652
  Kino.listen(form, fn
653
  %{
654
  data: %{repo: repo, github_token: gh_tok, openai_token: oai_tok, model: model},
@@ -656,55 +672,57 @@ Kino.listen(form, fn
656
  } ->
657
  LiveReport.loading(live_report, origin)
658
 
659
- new_html =
660
- cond do
661
- repo == "" ->
662
- LiveReport.replace(live_report, {:error, "Please specify a GitHub Repo"}, origin)
663
 
664
- gh_tok == "" ->
665
- LiveReport.replace(live_report, {:error, "Please specify a GitHub Token"}, origin)
666
 
667
- oai_tok == "" ->
668
- LiveReport.replace(live_report, {:error, "Please specify an OpenAI Token"}, origin)
669
 
670
- model == "" ->
671
- LiveReport.replace(live_report, {:error, "Please specify an OpenAI model"}, origin)
672
 
673
- true ->
674
- case repo |> ReportGenerator.generate_report(gh_tok, oai_tok, model) do
675
- {:ok, report} ->
676
- LiveReport.replace(live_report, report, origin)
677
 
678
- {:error, reason} ->
679
- cond do
680
- String.contains?(reason, "invalid_api_key") ->
681
- LiveReport.replace(live_report, {:error, "Invalid OpenAI API Key"}, origin)
682
 
683
- String.contains?(reason, "invalid model ID") or
684
- String.contains?(reason, "model_not_found") ->
685
- LiveReport.replace(live_report, {:error, "Invalid OpenAI Model"}, origin)
686
 
687
- true ->
688
- LiveReport.replace(live_report, {:error, reason}, origin)
689
- end
690
- end
691
- end
692
-
693
- Kino.Frame.render(frame, Kino.Text.new(new_html, terminal: false))
694
  end)
695
 
696
- download =
697
- Kino.Download.new(
698
- fn ->
699
- Kino.Frame.get_outputs(frame)
700
- |> hd()
701
- |> Map.get(:text)
702
- end,
703
- label: "Download Report",
704
- filename: "report.html"
705
- )
706
 
707
- Kino.Layout.grid([instructions, form, live_report, download], columns: 1, gap: 4, boxed: true)
 
 
 
 
 
 
 
 
 
 
708
  ```
709
 
710
- <!-- livebook:{"offset":31074,"stamp":{"token":"XCP.onc6e6vcHY1ankirQw_JV6eLv2buba18ObiQngfKw-jQRGz99wvgiH_rRYsSTS5hOpf4k98j_4lCg9GY6ybuR8V7DvPj5PIeLI-HSkbmPlRHSspblkk_pLcdRPIbTr0Y6CGhoPyzov0","version":2}} -->
 
385
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
386
  </head>
387
  <body>
388
+ <div class="relative block w-full rounded-lg border-2 border-dashed border-gray-300 p-12 text-center focus:outline-none">
389
  <svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
390
  <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
391
  </svg>
392
  <span class="mt-2 block text-sm font-semibold text-gray-900">Generate Your Report to See it Here!</span>
393
+ </div>
394
  </body>
395
  </html>
396
  """
 
407
  Kino.JS.Live.call(kino, {:replace, :loading, origin})
408
  end
409
 
410
+ def download_html(kino, origin) do
411
+ Kino.JS.Live.call(kino, {:download, origin})
412
  end
413
 
414
  defp format_category(category) do
 
430
  end
431
 
432
  @impl true
433
+ def handle_call({:download, origin}, _from, ctx) do
434
+ send_event(ctx, origin, "download", nil)
435
+ {:reply, :ok, ctx}
436
  end
437
 
438
  def handle_call({:replace, %Report{} = report, origin}, _from, ctx) do
 
447
  <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
448
  </head>
449
  <body class="bg-gray-100">
450
+ <div id="report" class="container mx-auto p-6 mt-10 max-w-4xl">
451
  <div class="bg-white shadow overflow-hidden sm:rounded-lg">
452
  <div class="px-4 py-5 sm:px-6">
453
  <h1 class="text-2xl leading-6 font-medium text-gray-900">Project Report</h1>
 
591
  ctx.root.innerHTML = html;
592
 
593
  ctx.handleEvent("replace", (html) => {
 
594
  ctx.root.innerHTML = html;
595
  });
596
+
597
+ ctx.handleEvent("download", ( ) => {
598
+ // Convert the clone's content to a string
599
+ const htmlContent = '<!DOCTYPE html>\\n<html>\\n' + ctx.root.innerHTML + '\\n</html>';
600
+
601
+ // Create a Blob with the HTML content
602
+ const blob = new Blob([htmlContent], { type: 'text/html' });
603
+
604
+ // Create a link element to trigger the download
605
+ const link = document.createElement('a');
606
+ link.href = URL.createObjectURL(blob);
607
+ link.download = 'report.html';
608
+
609
+ // Append the link to the body, click it, and then remove it
610
+ document.body.appendChild(link);
611
+ link.click();
612
+ document.body.removeChild(link);
613
+ });
614
  }
615
  """
616
  end
 
665
  submit: "Generate"
666
  )
667
 
 
 
668
  Kino.listen(form, fn
669
  %{
670
  data: %{repo: repo, github_token: gh_tok, openai_token: oai_tok, model: model},
 
672
  } ->
673
  LiveReport.loading(live_report, origin)
674
 
675
+ cond do
676
+ repo == "" ->
677
+ LiveReport.replace(live_report, {:error, "Please specify a GitHub Repo"}, origin)
 
678
 
679
+ gh_tok == "" ->
680
+ LiveReport.replace(live_report, {:error, "Please specify a GitHub Token"}, origin)
681
 
682
+ oai_tok == "" ->
683
+ LiveReport.replace(live_report, {:error, "Please specify an OpenAI Token"}, origin)
684
 
685
+ model == "" ->
686
+ LiveReport.replace(live_report, {:error, "Please specify an OpenAI model"}, origin)
687
 
688
+ true ->
689
+ case repo |> ReportGenerator.generate_report(gh_tok, oai_tok, model) do
690
+ {:ok, report} ->
691
+ LiveReport.replace(live_report, report, origin)
692
 
693
+ {:error, reason} ->
694
+ cond do
695
+ String.contains?(reason, "invalid_api_key") ->
696
+ LiveReport.replace(live_report, {:error, "Invalid OpenAI API Key"}, origin)
697
 
698
+ String.contains?(reason, "invalid model ID") or
699
+ String.contains?(reason, "model_not_found") ->
700
+ LiveReport.replace(live_report, {:error, "Invalid OpenAI Model"}, origin)
701
 
702
+ true ->
703
+ LiveReport.replace(live_report, {:error, reason}, origin)
704
+ end
705
+ end
706
+ end
 
 
707
  end)
708
 
709
+ downloadButton = Kino.Control.button("Download Report")
710
+
711
+ Kino.listen(downloadButton, fn %{type: :click, origin: origin} ->
712
+ LiveReport.download_html(live_report, origin)
713
+ end)
 
 
 
 
 
714
 
715
+ Kino.Layout.grid(
716
+ [
717
+ instructions,
718
+ form,
719
+ live_report,
720
+ downloadButton
721
+ ],
722
+ columns: 1,
723
+ gap: 6,
724
+ boxed: true
725
+ )
726
  ```
727
 
728
+ <!-- livebook:{"offset":31645,"stamp":{"token":"XCP.lEznQ8gJ-Q4vQRtuuYZFNEAQ4dX43lDK0WJaCsYxrBvxtKGbDAH-9RpliYFJnPG0s_CcYj0ziZn-Jr4mBGR_35xi0YReFTFGGJPx5wOL7dBA7v97nK8p95TzsTOtcoCKQpLFbY0UYjA","version":2}} -->