Skip to content

Commit

Permalink
feat: added a dynamic parser on the frontend with immediate feedback (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Skarlso authored Oct 11, 2024
1 parent 2af7e3a commit 2ffd548
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 35 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

Generate a sample YAML file from a CRD definition.

## Dynamic CRD Parsing on the frontend

![dynamic parsing](./imgs/dynamic-editing-showcase.gif)

## CRD Testing using CTY

For more information about how to use `cty` for helm-like unit testing your CRD schemas,
Expand Down
Binary file added imgs/dynamic-editing-showcase.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions wasm/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ func (h *crdView) OnNav(ctx app.Context) {
h.content = content
}

// The Render method is where the component appearance is defined. Here, a
// "Hello World!" is displayed as a heading.
// The Render method is where the component appearance is defined.
func (h *crdView) Render() app.UI {
if h.preRenderErr != nil {
return h.buildError(h.preRenderErr)
Expand Down
82 changes: 71 additions & 11 deletions wasm/index.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package main

import (
"bytes"
"errors"
"fmt"
"net/http"

"github.com/maxence-charriere/go-app/v10/pkg/app"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/util/yaml"

"github.com/Skarlso/crd-to-sample-yaml/pkg"
"github.com/Skarlso/crd-to-sample-yaml/pkg/fetcher"
"github.com/Skarlso/crd-to-sample-yaml/pkg/sanitize"
)
Expand Down Expand Up @@ -219,20 +223,76 @@ func (i *index) NavBackOnClick(_ app.Context, _ app.Event) {
i.content = nil
}

type editView struct {
app.Compo

content []byte
}

func (e *editView) OnInput(ctx app.Context, _ app.Event) {
content := ctx.JSSrc().Get("value").String()

crd := &v1.CustomResourceDefinition{}
if err := yaml.Unmarshal([]byte(content), crd); err != nil {
e.content = []byte("invalid CRD content")

return
}

e.content = nil

parser := pkg.NewParser(crd.Spec.Group, crd.Spec.Names.Kind, false, false, false)
for _, version := range crd.Spec.Versions {
e.content = append(e.content, []byte("---\n")...)
var buffer []byte
buf := bytes.NewBuffer(buffer)
if err := parser.ParseProperties(version.Name, buf, version.Schema.OpenAPIV3Schema.Properties); err != nil {
e.content = []byte(err.Error())

return
}
e.content = append(e.content, buf.Bytes()...)
}
}

func (e *editView) Render() app.UI {
return app.Div().Body(
app.H6().Text("Dynamically render CRD content"),
app.Div().Class("input-group input-group-lg").Body(
app.Div().Class("container").Body(
app.Div().Class("row justify-content-around").Body(
app.Textarea().Class("col form-control").Style("height", "350px").Style("max-height", "800px").Placeholder("Start typing...").ID("input-area").OnInput(e.OnInput),
// app.Pre().Class("col").Body(
// app.Code().Style("height", "250px").Style("max-height", "800px").Class("language-yaml").ID("output-area").Body(
// app.Text(string(e.content)),
// )),
app.Textarea().Class("col form-control").Style("height", "350px").Style("max-height", "800px").ID("output-area").Text(string(e.content)),
),
),
))
}

func (i *index) Render() app.UI {
// Prevent double rendering components.
if i.isMounted {
return app.Main().Body(app.Div().Class("container").Body(func() app.UI {
if i.err != nil {
return app.Div().Class("container").Body(&header{titleOnClick: i.NavBackOnClick, hidden: true}, i.buildError())
}

if i.content != nil {
return &crdView{content: i.content, comment: i.comments, minimal: i.minimal, navigateBackOnClick: i.NavBackOnClick}
}

return app.Div().Class("container").Body(&header{titleOnClick: i.NavBackOnClick, hidden: true}, &form{formHandler: i.OnClick, checkHandlerComment: i.OnCheckComment, checkHandlerMinimal: i.OnCheckMinimal})
}()))
return app.Main().Body(
app.Script().Src("https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"),
app.Script().Src("https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"),
app.Div().Class("container").Body(func() app.UI {
if i.err != nil {
return app.Div().Class("container").Body(&header{titleOnClick: i.NavBackOnClick, hidden: true}, i.buildError())
}

if i.content != nil {
return &crdView{content: i.content, comment: i.comments, minimal: i.minimal, navigateBackOnClick: i.NavBackOnClick}
}

return app.Div().Class("container").Body(
&header{titleOnClick: i.NavBackOnClick, hidden: true},
&editView{},
app.Div().Body(app.H6().Text("Render web view of CRD content")),
&form{formHandler: i.OnClick, checkHandlerComment: i.OnCheckComment, checkHandlerMinimal: i.OnCheckMinimal})
}()))
}

return app.Main()
Expand Down
18 changes: 9 additions & 9 deletions wasm/index.html
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<!DOCTYPE html>
<html data-bs-core="modern" data-bs-theme="dark" lang="en">
<html data-bs-theme="dark" lang="en" data-bs-core="modern">
<head>
<meta charset="UTF-8">
<meta name="author" content="Gergely Brautigam">
<meta name="description" content>
<meta name="theme-color" content="#2d2c2c">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover">
<meta property="og:url" content="https://">
<meta content="Preview CRDs" property="og:title">
<meta property="og:title" content="Preview CRDs">
<meta property="og:description" content>
<meta property="og:type" content="website">
<meta property="og:image" content="https://">
<title>Preview CRDs</title>
<link href="/app.css" type="text/css" rel="preload" as="style">
<link as="style" href="/web/css/alert.css" type="text/css" rel="preload">
<link as="style" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-twilight.min.css" type="text/css" rel="preload">
<link rel="preload" as="style" href="/web/css/alert.css" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-twilight.min.css" type="text/css" rel="preload" as="style">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css" type="text/css" rel="preload" as="style">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/cores/halfmoon.modern.css" type="text/css" rel="preload" as="style">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css" rel="preload" as="style">
<link as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css" rel="preload">
<link rel="icon" href="https://raw.githubusercontent.com/maxence-charriere/go-app/master/docs/web/icon.svg">
<link rel="apple-touch-icon" href="/web/img/logo.png">
<link href="/manifest.webmanifest" rel="manifest">
<link href="/web/img/logo.png" rel="apple-touch-icon">
<link rel="manifest" href="/manifest.webmanifest">
<link href="/app.css" type="text/css" rel="stylesheet">
<link href="/web/css/alert.css" type="text/css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-twilight.min.css" type="text/css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css" type="text/css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css" type="text/css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/cores/halfmoon.modern.css" type="text/css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css" rel="stylesheet">
<script defer src="/wasm_exec.js"></script>
Expand Down Expand Up @@ -64,7 +64,7 @@
<main></main>
<aside id="app-wasm-loader" class="goapp-app-info">
<img id="app-wasm-loader-icon" class="goapp-logo goapp-spin" alt="wasm loader icon" src="/web/img/logo.png">
<p id="app-wasm-loader-label" class="goapp-label">0%</p>
<p class="goapp-label" id="app-wasm-loader-label">0%</p>
</aside>
</body>
</html>
26 changes: 13 additions & 13 deletions wasm/share.html
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
<!DOCTYPE html>
<html lang="en" data-bs-core="modern" data-bs-theme="dark">
<html data-bs-theme="dark" lang="en" data-bs-core="modern">
<head>
<meta charset="UTF-8">
<meta name="author" content="Gergely Brautigam">
<meta name="description" content>
<meta name="theme-color" content="#2d2c2c">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover">
<meta property="og:url" content="https:///share">
<meta content="Preview CRDs" property="og:title">
<meta property="og:title" content="Preview CRDs">
<meta property="og:description" content>
<meta property="og:type" content="website">
<meta property="og:image" content="https://">
<title>Preview CRDs</title>
<link as="style" href="/app.css" type="text/css" rel="preload">
<link type="text/css" rel="preload" as="style" href="/web/css/alert.css">
<link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-twilight.min.css" type="text/css">
<link as="style" href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css" type="text/css" rel="preload">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/cores/halfmoon.modern.css" type="text/css" rel="preload" as="style">
<link rel="preload" as="style" href="/app.css" type="text/css">
<link href="/web/css/alert.css" type="text/css" rel="preload" as="style">
<link type="text/css" rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-twilight.min.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css" type="text/css" rel="preload" as="style">
<link type="text/css" rel="preload" as="style" href="https://cdn.jsdelivr.net/npm/[email protected]/css/cores/halfmoon.modern.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css" rel="preload" as="style">
<link rel="icon" href="https://raw.githubusercontent.com/maxence-charriere/go-app/master/docs/web/icon.svg">
<link rel="apple-touch-icon" href="/web/img/logo.png">
<link rel="manifest" href="/manifest.webmanifest">
<link href="/app.css" type="text/css" rel="stylesheet">
<link href="/manifest.webmanifest" rel="manifest">
<link type="text/css" rel="stylesheet" href="/app.css">
<link href="/web/css/alert.css" type="text/css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-twilight.min.css" type="text/css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css" type="text/css" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/halfmoon.min.css">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/css/cores/halfmoon.modern.css" type="text/css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css" rel="stylesheet">
<script defer src="/wasm_exec.js"></script>
<script src="/app.js" defer></script>
<script defer src="/app.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script>
<meta charset="utf-8">
Expand Down Expand Up @@ -66,7 +66,7 @@
<h4 class="alert-heading">Oops!</h4>
url parameter has to be define in the following format: /share?url=https://example.com/crd.yaml
</div>
<aside class="goapp-app-info" id="app-wasm-loader">
<aside id="app-wasm-loader" class="goapp-app-info">
<img src="/web/img/logo.png" id="app-wasm-loader-icon" class="goapp-logo goapp-spin" alt="wasm loader icon">
<p id="app-wasm-loader-label" class="goapp-label">0%</p>
</aside>
Expand Down
Binary file modified wasm/web/app.wasm
Binary file not shown.

0 comments on commit 2ffd548

Please sign in to comment.