add edit page

This commit is contained in:
Alexander Foremny
2024-06-05 10:41:02 +02:00
parent d5f3f2333a
commit a7a4dd0112
7 changed files with 111 additions and 6 deletions

View File

@@ -28,6 +28,7 @@ rec {
haskellPackages.frontend haskellPackages.frontend
]; ];
buildInputs = [ buildInputs = [
haskellPackages.astore
haskellPackages.cabal-install haskellPackages.cabal-install
haskellPackages.ormolu haskellPackages.ormolu
(pkgs.writeScriptBin "reload" '' (pkgs.writeScriptBin "reload" ''

View File

@@ -3,6 +3,8 @@
module Api module Api
( fetchSchema, ( fetchSchema,
fetchPosts, fetchPosts,
fetchPost,
updatePost,
) )
where where
@@ -18,8 +20,10 @@ import Miso.String qualified as J
#endif #endif
import Data.Aeson qualified as A import Data.Aeson qualified as A
import Data.ByteString.Lazy.Char8 qualified as LB import Data.ByteString.Lazy.Char8 qualified as LB
import Data.ByteString.Lazy.UTF8 qualified as LB
import Data.Function import Data.Function
import Miso import Miso
import Safe
import Schema import Schema
fetchSchema :: JSM (Either String Schema) fetchSchema :: JSM (Either String Schema)
@@ -35,6 +39,24 @@ fetchPosts =
& setRequestBodyLBS "SELECT posts FROM posts" & setRequestBodyLBS "SELECT posts FROM posts"
) )
fetchPost :: String -> JSM (Either String (Maybe A.Value))
fetchPost fileName =
fmap headMay . A.eitherDecode
<$> fetch
( fromString "http://localhost:8081"
& setRequestMethod "POST"
& setRequestBodyLBS ("SELECT posts FROM posts WHERE posts.$fileName == \"" <> LB.fromString fileName <> "\"")
)
updatePost :: String -> A.Value -> JSM (Either String ())
updatePost fileName value =
A.eitherDecode
<$> fetch
( fromString "http://localhost:8081"
& setRequestMethod "POST"
& setRequestBodyLBS ("UPDATE posts SET " <> A.encode value <> " WHERE posts.$fileName == \"" <> LB.fromString fileName <> "\"")
)
fetch :: Request -> JSM LB.ByteString fetch :: Request -> JSM LB.ByteString
fetch req = LB.fromStrict . getResponseBody <$> httpBS req fetch req = LB.fromStrict . getResponseBody <$> httpBS req

View File

@@ -11,6 +11,7 @@ import Data.Bifunctor
import Data.Default import Data.Default
import Data.Function import Data.Function
import Miso import Miso
import Page.EditValue qualified as EditValue
import Page.ListCollection qualified as ListCollection import Page.ListCollection qualified as ListCollection
import Route (Route) import Route (Route)
import Route qualified as Route import Route qualified as Route
@@ -18,26 +19,35 @@ import Route qualified as Route
data Page data Page
= Home = Home
| ListCollection ListCollection.Model | ListCollection ListCollection.Model
| EditValue EditValue.Model
deriving (Show, Eq)
data Action
= HandleListCollection ListCollection.Action
| HandleEditValue EditValue.Action
deriving (Show, Eq) deriving (Show, Eq)
instance Default Page where instance Default Page where
def = Home def = Home
data Action
= HandleListCollection ListCollection.Action
deriving (Show, Eq)
initialPage :: Route -> JSM (Either String Page) initialPage :: Route -> JSM (Either String Page)
initialPage Route.Home = pure (Right Home) initialPage Route.Home = pure (Right Home)
initialPage (Route.ListCollection c) = initialPage (Route.ListCollection c) =
fmap ListCollection <$> ListCollection.initialModel c fmap ListCollection <$> ListCollection.initialModel c
initialPage (Route.EditValue c f) =
fmap EditValue <$> EditValue.initialModel c f
updatePage :: Action -> Page -> Effect Action Page updatePage :: Action -> Page -> Effect Action Page
updatePage (HandleListCollection action) (ListCollection m) = updatePage (HandleListCollection action) (ListCollection m) =
ListCollection.updateModel action m ListCollection.updateModel action m
& bimap HandleListCollection ListCollection & bimap HandleListCollection ListCollection
updatePage (HandleListCollection _) p = noEff p updatePage (HandleListCollection _) p = noEff p
updatePage (HandleEditValue action) (EditValue m) =
EditValue.updateModel action m
& bimap HandleEditValue EditValue
updatePage (HandleEditValue _) p = noEff p
viewPage :: Page -> View Action viewPage :: Page -> View Action
viewPage Home = text "home" viewPage Home = text "home"
viewPage (ListCollection m) = HandleListCollection <$> ListCollection.viewModel m viewPage (ListCollection m) = HandleListCollection <$> ListCollection.viewModel m
viewPage (EditValue m) = HandleEditValue <$> EditValue.viewModel m

View File

@@ -0,0 +1,66 @@
module Page.EditValue
( Model,
initialModel,
Action,
updateModel,
viewModel,
)
where
import Api
import Data.Aeson qualified as A
import Data.Aeson.KeyMap qualified as AM
import Data.Maybe
import Form qualified as F
import Miso
import Miso.String (toMisoString)
import Schema
data Model = Model
{ collection :: String,
fileName :: String,
input :: Maybe A.Value,
schema :: Schema
}
deriving (Show, Eq)
initialModel :: String -> String -> JSM (Either String Model)
initialModel collection fileName = do
schema' <- fetchSchema
input' <- fetchPost fileName
pure do
schema <- schema'
input <- input'
pure $ Model {..}
data Action
= NoOp
| FormChanged A.Value
| FormSubmitted A.Value
| EntityWritten (Either String ())
deriving (Eq, Show)
updateModel :: Action -> Model -> Effect Action Model
updateModel NoOp m = noEff m
updateModel (FormChanged (Just -> input)) m = noEff m {input}
updateModel (FormSubmitted output) m =
m <# do EntityWritten <$> updatePost m.fileName output
updateModel (EntityWritten _) m = noEff m
viewModel :: Model -> View Action
viewModel m = do
let input = (fromMaybe (A.Object AM.empty) m.input)
div_ [] $
[ viewForm input m.schema,
viewInput input
]
viewForm :: A.Value -> Schema -> View Action
viewForm input =
fmap (either FormChanged FormSubmitted)
. flip F.runForm input
. schemaForm
viewInput :: A.Value -> View Action
viewInput input =
pre_ [] [text (toMisoString (A.encode input))]

View File

@@ -12,6 +12,7 @@ import Miso
data Route data Route
= Home = Home
| ListCollection String | ListCollection String
| EditValue String String
deriving (Show, Eq) deriving (Show, Eq)
instance Default Route where instance Default Route where
@@ -22,7 +23,10 @@ parseURI uri =
either (const def) id $ either (const def) id $
P.parseOnly P.parseOnly
( P.choice ( P.choice
[ ListCollection <$> (P.string "#collection/" *> P.many1 P.anyChar), [ EditValue
<$> (P.string "#collection/" *> P.manyTill P.anyChar (P.string "/"))
<*> (P.many1 P.anyChar),
ListCollection <$> (P.string "#collection/" *> P.many1 P.anyChar),
pure Home pure Home
] ]
<* P.endOfInput <* P.endOfInput

View File

@@ -17,6 +17,7 @@ executable frontend
Form.Input Form.Input
Form.Internal Form.Internal
Page Page
Page.EditValue
Page.ListCollection Page.ListCollection
Route Route
Schema Schema
@@ -40,6 +41,7 @@ executable frontend
data-default, data-default,
miso, miso,
neat-interpolation, neat-interpolation,
safe,
text, text,
utf8-string utf8-string

View File

@@ -2,7 +2,7 @@
"json2sql": { "json2sql": {
"branch": "main", "branch": "main",
"repo": "git@code.nomath.org:~/json2sql", "repo": "git@code.nomath.org:~/json2sql",
"rev": "bbe3b75bfd0767c61bcd436e843b9c785efd289f", "rev": "04b43e75fb0822de7db67f108c3545dee451069c",
"type": "git" "type": "git"
}, },
"nixpkgs": { "nixpkgs": {