git.iko.soy/rowtype-yoga/psfp
on master help sign in
more client
a6e8f77Mark Eibes
client/src/CompileEditor/Component.pursnew file+74
@@ -0,0 +1,74 @@
1+module CompileEditor.Component where
2+
3+import Prelude hiding (add)
4+import Button.Component (ButtonType(..), mkButton)
5+import Card.Component (mkCard)
6+import Data.Foldable (for_)
7+import Data.Nullable (null)
8+import Data.Tuple.Nested ((/\))
9+import Editor (getValue, mkEditor)
10+import Effect (Effect)
11+import Effect.Aff (Aff, launchAff_)
12+import Effect.Class (liftEffect)
13+import Milkis as M
14+import Milkis.Impl.Window (windowFetch)
15+import React.Basic (ReactComponent)
16+import React.Basic.DOM (css)
17+import React.Basic.DOM as R
18+import React.Basic.Events (handler_)
19+import React.Basic.Hooks (component, element, fragment, readRefMaybe, useRef, useState)
20+import React.Basic.Hooks as React
21+import Shared.Json (readAff)
22+import Shared.Models.Body as Body
23+import Simple.JSON (writeJSON)
24+
25+mkCompileEditor ∷ Effect (ReactComponent {})
26+mkCompileEditor = do
27+ editor <- mkEditor
28+ card <- mkCard
29+ button <- mkButton
30+ component "StorybookEditor" \{} -> React.do
31+ editorRef <- useRef null
32+ compileResult /\ modifyCompileResult <- useState ""
33+ let
34+ setCompileResult = modifyCompileResult <<< const
35+ pure
36+ $ fragment
37+ [ element button
38+ { buttonType: PlainButton
39+ , children: [ R.text "Compile"]
40+ , buttonProps:
41+ { onClick:
42+ handler_ do
43+ maybeEditor <- (readRefMaybe editorRef)
44+ for_ maybeEditor \ed -> do
45+ code <- getValue ed
46+ launchAff_ do
47+ res <- compile { code }
48+ res2 <- run
49+ setCompileResult res2.stdout # liftEffect
50+ }
51+ }
52+ , element card { children: [ R.text compileResult ] }
53+ , R.div { children: [ element editor { editorRef } ], style: css { height: "100%" } }
54+ ]
55+
56+fetch ∷ M.Fetch
57+fetch = M.fetch windowFetch
58+
59+compile ∷ Body.CompileRequest -> Aff Body.CompileResult
60+compile body = do
61+ fetch (M.URL "/api/compile")
62+ { method: M.postMethod
63+ , body: writeJSON body
64+ , headers: M.makeHeaders { "Content-Type": "application/json" }
65+ }
66+ >>= M.json
67+ >>= readAff
68+
69+run ∷ Aff Body.RunResult
70+run = do
71+ fetch (M.URL "/api/run")
72+ { method: M.postMethod }
73+ >>= M.json
74+ >>= readAff
client/src/Container/Component.purs+6−2
@@ -3,14 +3,16 @@ module Container.Component where
3import Prelude
3import Prelude
4
4
5import CSS.Safer (cssSafer)
5import CSS.Safer (cssSafer)
6+import CompileEditor.Component (mkCompileEditor)
6import Container.Header (mkHeader)
7import Container.Header (mkHeader)
7import Container.Landing (mkLandingPage)
8import Container.Landing (mkLandingPage)
8import Container.Sidebar (mkSidebar, mkSidebarLink)
9import Container.Sidebar (mkSidebar, mkSidebarLink)
10+import Data.Nullable as Nullable
9import Effect (Effect)
11import Effect (Effect)
10import Polyfill.SmoothScrolling (smoothScrollPolyfill)
12import Polyfill.SmoothScrolling (smoothScrollPolyfill)
11import React.Basic (JSX)
13import React.Basic (JSX)
12import React.Basic.DOM as R
14import React.Basic.DOM as R
13−import React.Basic.Hooks ((/\), ReactComponent, component, element, useState)
15+import React.Basic.Hooks (ReactComponent, component, element, useRef, useState, (/\))
14import React.Basic.Hooks as React
16import React.Basic.Hooks as React
15import SVG.Icon (appendIcon, applyflippedIcon, bindIcon, mapIcon)
17import SVG.Icon (appendIcon, applyflippedIcon, bindIcon, mapIcon)
16import Theme.Provider (mkThemeProvider)
18import Theme.Provider (mkThemeProvider)
@@ -63,9 +65,11 @@ mkContainerContent = do
63 sidebar <- mkSidebar
65 sidebar <- mkSidebar
64 header <- mkHeader
66 header <- mkHeader
65 sidebarLink <- mkSidebarLink
67 sidebarLink <- mkSidebarLink
68+ editor <- mkCompileEditor
66 component "ContainerContent" \{ children } -> React.do
69 component "ContainerContent" \{ children } -> React.do
67 classes <- useStyles
70 classes <- useStyles
68 collapsed /\ modifyCollapsed <- useState true
71 collapsed /\ modifyCollapsed <- useState true
72+ editorRef <- useRef Nullable.null
69 pure
73 pure
70 $ R.div
74 $ R.div
71 { className: classes.container
75 { className: classes.container
@@ -82,6 +86,6 @@ mkContainerContent = do
82 ]
86 ]
83 }
87 }
84 , element header {}
88 , element header {}
85− , R.div { className: classes.content, children }
89+ , R.div { className: classes.content, children: [element editor {}] <> children }
86 ]
90 ]
87 }
91 }
client/src/Container/Header.purs+1−1
@@ -62,7 +62,7 @@ mkHeader = do
62 { ref: nodeRef
62 { ref: nodeRef
63 , className: classes.header <> " " <> guard shouldBeSticky classes.sticky
63 , className: classes.header <> " " <> guard shouldBeSticky classes.sticky
64 , children:
64 , children:
65− [ element h { level: H2, text: "Kleislove", className: Just classes.title }
65+ [ element h { level: H2, text: "Rowtype Yoga", className: Just classes.title }
66 , R.div { children: [ element trianglelogoIcon {} ], className: classes.logo }
66 , R.div { children: [ element trianglelogoIcon {} ], className: classes.logo }
67 ]
67 ]
68 }
68 }
client/src/Monaco/Editor.purs+1
@@ -117,6 +117,7 @@ mkEditor = do
117 , lineDecorationsWidth: 0
117 , lineDecorationsWidth: 0
118 , lineNumbersMinChars: 0
118 , lineNumbersMinChars: 0
119 , minimap: { enabled: false }
119 , minimap: { enabled: false }
120+ , automaticLayout: true
120 }
121 }
121 , language: "purescript"
122 , language: "purescript"
122 -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
123 -- https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages