add schema version
This commit is contained in:
@@ -15,6 +15,8 @@ import Data.ByteString.Lazy.UTF8 qualified as LB
|
|||||||
import Data.ByteString.UTF8 qualified as B
|
import Data.ByteString.UTF8 qualified as B
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Map qualified as M
|
import Data.Map qualified as M
|
||||||
|
import Data.Map.Merge.Strict qualified as M
|
||||||
|
import Data.Maybe
|
||||||
import Data.String (IsString (fromString))
|
import Data.String (IsString (fromString))
|
||||||
import Data.Tagged (Tagged (..), untag)
|
import Data.Tagged (Tagged (..), untag)
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
@@ -25,11 +27,13 @@ import Network.HTTP.Types.Status qualified as W
|
|||||||
import Network.Wai qualified as W
|
import Network.Wai qualified as W
|
||||||
import Network.Wai.Handler.Warp qualified as W
|
import Network.Wai.Handler.Warp qualified as W
|
||||||
import Options.Applicative qualified as A
|
import Options.Applicative qualified as A
|
||||||
|
import Safe
|
||||||
import Store qualified as Q
|
import Store qualified as Q
|
||||||
import System.Directory (setCurrentDirectory)
|
import System.Directory (setCurrentDirectory)
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.INotify
|
import System.INotify
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
|
import Version
|
||||||
|
|
||||||
data Args = Args
|
data Args = Args
|
||||||
{ cmd :: Cmd
|
{ cmd :: Cmd
|
||||||
@@ -57,7 +61,8 @@ data Repo = Repo
|
|||||||
|
|
||||||
data Commit = Commit
|
data Commit = Commit
|
||||||
{ id :: G.CommitOid GB.LgRepo,
|
{ id :: G.CommitOid GB.LgRepo,
|
||||||
collections :: [Collection]
|
collections :: [Collection],
|
||||||
|
schemaVersion :: Version
|
||||||
}
|
}
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
@@ -110,22 +115,78 @@ initRepo root ref = do
|
|||||||
Just cid <- fmap Tagged <$> G.resolveReference ref
|
Just cid <- fmap Tagged <$> G.resolveReference ref
|
||||||
c <- G.lookupCommit cid
|
c <- G.lookupCommit cid
|
||||||
cs <- mapM G.lookupCommit =<< G.listCommits Nothing cid
|
cs <- mapM G.lookupCommit =<< G.listCommits Nothing cid
|
||||||
fmap Repo . forM cs $ \c -> do
|
fmap (Repo . reverse) $
|
||||||
let cid = G.commitOid c
|
foldM
|
||||||
fs <-
|
( \cs c -> do
|
||||||
fmap (filter ((== ".json") . takeExtension)) . liftIO $
|
let cid = G.commitOid c
|
||||||
Q.withStore root ref do
|
fs <-
|
||||||
Q.withCommit cid Q.listAllFiles
|
fmap (filter ((== ".json") . takeExtension)) . liftIO $
|
||||||
let cls =
|
Q.withStore root ref do
|
||||||
M.toList . M.unionsWith (++) $
|
Q.withCommit cid (Q.listFiles "/")
|
||||||
map (\f -> M.singleton (takeDirectory f) [f]) fs
|
let cls =
|
||||||
colls <- forM cls $ \(makeRelative "/" -> path, (file : files)) -> do
|
M.toList . M.unionsWith (++) $
|
||||||
(value : values) <- do
|
map (\f -> M.singleton (takeDirectory f) [f]) fs
|
||||||
liftIO $ Q.withStore root ref do
|
colls <- forM cls $ \(path, (file : files)) -> do
|
||||||
mapM (Q.withCommit cid . Q.readFile) (file : files)
|
(value : values) <- do
|
||||||
let schema = fromAutoTypes path $ U.autoTypes' value values
|
liftIO $ Q.withStore root ref do
|
||||||
pure $ Collection path files schema
|
mapM (Q.withCommit cid . Q.readFile) (file : files)
|
||||||
pure (Commit cid colls)
|
let schema = fromAutoTypes path $ U.autoTypes' value values
|
||||||
|
pure $ Collection path files schema
|
||||||
|
let schemaVersion =
|
||||||
|
case lastMay cs of
|
||||||
|
Nothing -> Version 1 0 0
|
||||||
|
Just c' ->
|
||||||
|
let Version major' minor' patch' = c'.schemaVersion
|
||||||
|
schemas' =
|
||||||
|
M.fromList
|
||||||
|
( (\coll -> (coll.path, coll.schema))
|
||||||
|
<$> c'.collections
|
||||||
|
)
|
||||||
|
schemas =
|
||||||
|
M.fromList
|
||||||
|
( (\coll -> (coll.path, coll.schema))
|
||||||
|
<$> c.collections
|
||||||
|
)
|
||||||
|
in case compareSchemas schemas' schemas of
|
||||||
|
Just Major -> Version (major' + 1) 0 0
|
||||||
|
Just Minor -> Version major' (minor' + 1) 0
|
||||||
|
Just Patch -> Version major' minor' (patch' + 1)
|
||||||
|
Nothing -> Version major' minor' patch'
|
||||||
|
c = Commit cid colls schemaVersion
|
||||||
|
pure (c : cs)
|
||||||
|
)
|
||||||
|
[]
|
||||||
|
cs
|
||||||
|
|
||||||
|
compareSchemas ::
|
||||||
|
M.Map String Schema ->
|
||||||
|
M.Map String Schema ->
|
||||||
|
Maybe SchemaDifference
|
||||||
|
compareSchemas schemas' schemas =
|
||||||
|
maximumMay
|
||||||
|
. catMaybes
|
||||||
|
. M.elems
|
||||||
|
. M.map (uncurry compareSchemas')
|
||||||
|
$ M.merge
|
||||||
|
(M.mapMissing (\_ schema' -> (Just schema', Nothing)))
|
||||||
|
(M.mapMissing (\_ schema -> (Nothing, Just schema)))
|
||||||
|
(M.zipWithMatched (\_ schema' schema -> (Just schema', Just schema)))
|
||||||
|
schemas'
|
||||||
|
schemas
|
||||||
|
where
|
||||||
|
compareSchemas' Nothing (Just _) = Just Patch
|
||||||
|
compareSchemas' (Just _) Nothing = Just Patch
|
||||||
|
compareSchemas' (Just schema') (Just schema) = compareSchema schema' schema
|
||||||
|
|
||||||
|
-- TODO
|
||||||
|
compareSchema :: Schema -> Schema -> Maybe SchemaDifference
|
||||||
|
compareSchema schema' schema = Nothing
|
||||||
|
|
||||||
|
data SchemaDifference
|
||||||
|
= Major
|
||||||
|
| Minor
|
||||||
|
| Patch
|
||||||
|
deriving (Eq, Ord)
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
@@ -146,21 +207,28 @@ main = do
|
|||||||
q <-
|
q <-
|
||||||
fromString @Q.Query . LB.toString
|
fromString @Q.Query . LB.toString
|
||||||
<$> W.lazyRequestBody req
|
<$> W.lazyRequestBody req
|
||||||
r <- liftIO $ Q.withStore root ref (Q.query q)
|
r <- liftIO $ Q.withStore root ref do Q.query q
|
||||||
respond . W.responseLBS W.status200 [] $ J.encode r
|
respond . W.responseLBS W.status200 [] $ J.encode r
|
||||||
(Debug.Trace.traceShowId -> !_) ->
|
Right SchemaVersion -> do
|
||||||
|
repo <- atomically (readTMVar repoT)
|
||||||
|
respond $
|
||||||
|
W.responseLBS W.status200 [] $
|
||||||
|
J.encode (last repo.commits).schemaVersion
|
||||||
|
(traceShowId -> !_) ->
|
||||||
respond $ W.responseLBS W.status200 [] "not implemented"
|
respond $ W.responseLBS W.status200 [] "not implemented"
|
||||||
|
|
||||||
data Route
|
data Route
|
||||||
= SchemaJson String
|
= SchemaJson String
|
||||||
| Query
|
| Query
|
||||||
|
| SchemaVersion
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
routeP :: P.Parser Route
|
routeP :: P.Parser Route
|
||||||
routeP =
|
routeP =
|
||||||
( P.choice
|
( P.choice
|
||||||
[ SchemaJson <$> (P.string "/" *> P.manyTill P.anyChar (P.string ".schema.json")),
|
[ SchemaJson <$> (P.string "/" *> P.manyTill P.anyChar (P.string ".schema.json")),
|
||||||
pure Query <* (P.string "/")
|
pure SchemaVersion <* P.string "/schemaVersion",
|
||||||
|
pure Query <* P.string "/"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
<* P.endOfInput
|
<* P.endOfInput
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ executable backend
|
|||||||
autotypes,
|
autotypes,
|
||||||
base,
|
base,
|
||||||
bytestring,
|
bytestring,
|
||||||
|
common,
|
||||||
containers,
|
containers,
|
||||||
directory,
|
directory,
|
||||||
filepath,
|
filepath,
|
||||||
@@ -33,8 +34,11 @@ executable backend
|
|||||||
http-types,
|
http-types,
|
||||||
mtl,
|
mtl,
|
||||||
optparse-applicative,
|
optparse-applicative,
|
||||||
|
safe,
|
||||||
|
split,
|
||||||
stm,
|
stm,
|
||||||
tagged,
|
tagged,
|
||||||
|
text,
|
||||||
utf8-string,
|
utf8-string,
|
||||||
wai,
|
wai,
|
||||||
warp
|
warp
|
||||||
|
|||||||
5
common/CHANGELOG.md
Normal file
5
common/CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Revision history for common
|
||||||
|
|
||||||
|
## 0.1.0.0 -- YYYY-mm-dd
|
||||||
|
|
||||||
|
* First version. Released on an unsuspecting world.
|
||||||
30
common/LICENSE
Normal file
30
common/LICENSE
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Copyright (c) 2024, Alexander Foremny
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of Alexander Foremny nor the names of other
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
21
common/common.cabal
Normal file
21
common/common.cabal
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
cabal-version: 3.4
|
||||||
|
name: common
|
||||||
|
version: 0.1.0.0
|
||||||
|
license: BSD-3-Clause
|
||||||
|
license-file: LICENSE
|
||||||
|
maintainer: aforemny@posteo.de
|
||||||
|
author: Alexander Foremny
|
||||||
|
build-type: Simple
|
||||||
|
extra-doc-files: CHANGELOG.md
|
||||||
|
|
||||||
|
library
|
||||||
|
exposed-modules: Version
|
||||||
|
hs-source-dirs: src
|
||||||
|
default-language: GHC2021
|
||||||
|
default-extensions: ViewPatterns
|
||||||
|
ghc-options: -Wall
|
||||||
|
build-depends:
|
||||||
|
aeson,
|
||||||
|
base,
|
||||||
|
split,
|
||||||
|
text
|
||||||
36
common/src/Version.hs
Normal file
36
common/src/Version.hs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
module Version
|
||||||
|
( Version (..),
|
||||||
|
versionToString,
|
||||||
|
versionFromText,
|
||||||
|
versionFromString,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Data.Aeson qualified as A
|
||||||
|
import Data.Aeson.Types qualified as A
|
||||||
|
import Data.List
|
||||||
|
import Data.List.Split
|
||||||
|
import Data.Text qualified as T
|
||||||
|
|
||||||
|
data Version = Version Int Int Int
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
instance A.ToJSON Version where
|
||||||
|
toJSON =
|
||||||
|
A.toJSON . versionToString
|
||||||
|
|
||||||
|
instance A.FromJSON Version where
|
||||||
|
parseJSON (A.String (versionFromText -> Just version)) = pure version
|
||||||
|
parseJSON v = A.typeMismatch "version" v
|
||||||
|
|
||||||
|
versionToString :: Version -> String
|
||||||
|
versionToString (Version major minor patch) =
|
||||||
|
intercalate "." (map show [major, minor, patch])
|
||||||
|
|
||||||
|
versionFromString :: String -> Maybe Version
|
||||||
|
versionFromString (map read . splitOn "." -> [major, minor, patch]) =
|
||||||
|
Just (Version major minor patch)
|
||||||
|
versionFromString _ = Nothing
|
||||||
|
|
||||||
|
versionFromText :: T.Text -> Maybe Version
|
||||||
|
versionFromText = versionFromString . T.unpack
|
||||||
@@ -7,6 +7,7 @@ let
|
|||||||
astore = self.callCabal2nix "astore" sources.json2sql { };
|
astore = self.callCabal2nix "astore" sources.json2sql { };
|
||||||
autotypes = self.callCabal2nix "autotypes" ./autotypes { };
|
autotypes = self.callCabal2nix "autotypes" ./autotypes { };
|
||||||
backend = self.callCabal2nix "backend" ./backend { };
|
backend = self.callCabal2nix "backend" ./backend { };
|
||||||
|
common = self.callCabal2nix "common" ./common { };
|
||||||
frontend = self.callCabal2nix "frontend" ./frontend { };
|
frontend = self.callCabal2nix "frontend" ./frontend { };
|
||||||
websockets = pkgs.haskell.lib.doJailbreak super.websockets;
|
websockets = pkgs.haskell.lib.doJailbreak super.websockets;
|
||||||
};
|
};
|
||||||
@@ -14,6 +15,7 @@ let
|
|||||||
|
|
||||||
jsHaskellPackages = pkgs.pkgsCross.ghcjs.haskell.packages.ghc98.override {
|
jsHaskellPackages = pkgs.pkgsCross.ghcjs.haskell.packages.ghc98.override {
|
||||||
overrides = self: super: {
|
overrides = self: super: {
|
||||||
|
common = self.callCabal2nix "common" ./common { };
|
||||||
frontend = self.callCabal2nix "frontend" ./frontend { };
|
frontend = self.callCabal2nix "frontend" ./frontend { };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -25,6 +27,7 @@ rec {
|
|||||||
packages = _: [
|
packages = _: [
|
||||||
haskellPackages.autotypes
|
haskellPackages.autotypes
|
||||||
haskellPackages.backend
|
haskellPackages.backend
|
||||||
|
haskellPackages.common
|
||||||
haskellPackages.frontend
|
haskellPackages.frontend
|
||||||
];
|
];
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
module Api
|
module Api
|
||||||
( fetchSchema,
|
( fetchSchema,
|
||||||
|
fetchSchemaVersion,
|
||||||
fetchPosts,
|
fetchPosts,
|
||||||
fetchPost,
|
fetchPost,
|
||||||
updatePost,
|
updatePost,
|
||||||
@@ -25,11 +26,16 @@ import Data.Function
|
|||||||
import Miso
|
import Miso
|
||||||
import Safe
|
import Safe
|
||||||
import Schema
|
import Schema
|
||||||
|
import Version
|
||||||
|
|
||||||
fetchSchema :: JSM (Either String Schema)
|
fetchSchema :: JSM (Either String Schema)
|
||||||
fetchSchema =
|
fetchSchema =
|
||||||
A.eitherDecode <$> fetch (fromString "http://localhost:8081/posts.schema.json")
|
A.eitherDecode <$> fetch (fromString "http://localhost:8081/posts.schema.json")
|
||||||
|
|
||||||
|
fetchSchemaVersion :: JSM (Either String Version)
|
||||||
|
fetchSchemaVersion =
|
||||||
|
A.eitherDecode <$> fetch (fromString "http://localhost:8081/schemaVersion")
|
||||||
|
|
||||||
fetchPosts :: JSM (Either String [A.Value])
|
fetchPosts :: JSM (Either String [A.Value])
|
||||||
fetchPosts =
|
fetchPosts =
|
||||||
A.eitherDecode
|
A.eitherDecode
|
||||||
|
|||||||
@@ -4,24 +4,38 @@ module Main where
|
|||||||
import Language.Javascript.JSaddle.Warp as JSaddle
|
import Language.Javascript.JSaddle.Warp as JSaddle
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
import Api
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.Default
|
import Data.Default
|
||||||
import Data.Function
|
import Data.Function
|
||||||
import GHC.Generics (Generic)
|
|
||||||
import Miso
|
import Miso
|
||||||
import Miso.String (toMisoString)
|
import Miso.String (toMisoString)
|
||||||
import NeatInterpolation qualified as Q
|
import NeatInterpolation qualified as Q
|
||||||
import Page (Page, initialPage, updatePage, viewPage)
|
import Page (Page, initialPage, updatePage, viewPage)
|
||||||
import Page qualified as Page
|
import Page qualified as Page
|
||||||
import Route (parseURI)
|
import Route (parseURI)
|
||||||
|
import Version
|
||||||
|
|
||||||
data Model = Model
|
data Model
|
||||||
{ page :: Maybe (Either String Page)
|
= Loading
|
||||||
|
| Failed String
|
||||||
|
| Loaded LoadedState
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data LoadedState = LoadedState
|
||||||
|
{ page :: Maybe (Either String Page),
|
||||||
|
schemaVersion :: Version
|
||||||
}
|
}
|
||||||
deriving (Show, Eq, Generic, Default)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
instance Default Model where
|
||||||
|
def = Loading
|
||||||
|
|
||||||
data Action
|
data Action
|
||||||
= NoOp
|
= -- Loading
|
||||||
|
SetLoaded (Either String LoadedState)
|
||||||
|
| -- Loaded
|
||||||
|
NoOp
|
||||||
| Init URI
|
| Init URI
|
||||||
| HandleURI URI
|
| HandleURI URI
|
||||||
| HandlePage Page.Action
|
| HandlePage Page.Action
|
||||||
@@ -50,34 +64,43 @@ main = runApp $ do
|
|||||||
logLevel = Off
|
logLevel = Off
|
||||||
|
|
||||||
updateModel :: Action -> Model -> Effect Action Model
|
updateModel :: Action -> Model -> Effect Action Model
|
||||||
updateModel NoOp m = noEff m
|
updateModel _ (Failed err) = noEff (Failed err)
|
||||||
updateModel (Init uri) m =
|
updateModel (Init uri) Loading =
|
||||||
m <# do
|
Loading <# do
|
||||||
SetPage <$> initialPage (parseURI uri)
|
page <- Just <$> initialPage (parseURI uri)
|
||||||
updateModel (HandleURI uri) m =
|
schemaVersion' <- fetchSchemaVersion
|
||||||
m <# do
|
pure $ SetLoaded do
|
||||||
|
schemaVersion <- schemaVersion'
|
||||||
|
pure LoadedState {..}
|
||||||
|
updateModel (Init _) m = noEff m
|
||||||
|
updateModel (SetLoaded (Left err)) Loading = noEff (Failed err)
|
||||||
|
updateModel (SetLoaded (Right state)) Loading = noEff (Loaded state)
|
||||||
|
updateModel (SetLoaded _) m = noEff m
|
||||||
|
updateModel _ Loading = noEff Loading
|
||||||
|
updateModel NoOp (Loaded s) = noEff (Loaded s)
|
||||||
|
updateModel (HandleURI uri) (Loaded s) =
|
||||||
|
Loaded s <# do
|
||||||
let route = parseURI uri
|
let route = parseURI uri
|
||||||
SetPage <$> initialPage route
|
SetPage <$> initialPage route
|
||||||
updateModel (SetPage page) m = noEff m {page = Just page}
|
updateModel (SetPage page) (Loaded s) = noEff (Loaded s {page = Just page})
|
||||||
updateModel (HandlePage action) m =
|
updateModel (HandlePage action) (Loaded s) =
|
||||||
case m.page of
|
case s.page of
|
||||||
Just (Right page) ->
|
Just (Right page) ->
|
||||||
updatePage action page
|
fmap Loaded $
|
||||||
& bimap HandlePage (\page -> m {page = Just (Right page)})
|
updatePage action page
|
||||||
_ -> noEff m
|
& bimap HandlePage (\page -> s {page = Just (Right page)})
|
||||||
|
_ -> noEff (Loaded s)
|
||||||
|
|
||||||
viewModel :: Model -> View Action
|
viewModel :: Model -> View Action
|
||||||
viewModel model =
|
viewModel Loading = text ".."
|
||||||
|
viewModel (Failed s) = err s
|
||||||
|
viewModel (Loaded s) =
|
||||||
div_ [] $
|
div_ [] $
|
||||||
[ viewCss,
|
[ viewCss,
|
||||||
viewHeader,
|
viewHeader s,
|
||||||
nav_ [] [viewCollections],
|
nav_ [] [viewCollections],
|
||||||
main_ [] $
|
main_ [] $
|
||||||
[ HandlePage
|
[ HandlePage <$> maybe (text "..") (either err viewPage) s.page
|
||||||
<$> maybe
|
|
||||||
(text "..")
|
|
||||||
(either err viewPage)
|
|
||||||
model.page
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -171,16 +194,19 @@ th, td {
|
|||||||
err :: String -> View action
|
err :: String -> View action
|
||||||
err = text . toMisoString . ("err! " <>)
|
err = text . toMisoString . ("err! " <>)
|
||||||
|
|
||||||
viewHeader :: View Action
|
viewHeader :: LoadedState -> View Action
|
||||||
viewHeader =
|
viewHeader s =
|
||||||
header_ [] $
|
header_ [] $
|
||||||
[ section_ [] [h1_ [] [a_ [href_ "#"] [text "acms"]]],
|
[ section_ [] [h1_ [] [a_ [href_ "#"] [text "acms"]]],
|
||||||
section_ [] [viewBranch]
|
section_ [] (viewBranch s)
|
||||||
]
|
]
|
||||||
|
|
||||||
viewBranch :: View Action
|
viewBranch :: LoadedState -> [View Action]
|
||||||
viewBranch =
|
viewBranch s =
|
||||||
select_ [] [option_ [] [text "main"]]
|
[ text (toMisoString (versionToString s.schemaVersion)),
|
||||||
|
text " ",
|
||||||
|
select_ [] [option_ [] [text "main"]]
|
||||||
|
]
|
||||||
|
|
||||||
viewCollections :: View Action
|
viewCollections :: View Action
|
||||||
viewCollections =
|
viewCollections =
|
||||||
|
|||||||
@@ -37,11 +37,13 @@ executable frontend
|
|||||||
attoparsec,
|
attoparsec,
|
||||||
base,
|
base,
|
||||||
bytestring,
|
bytestring,
|
||||||
|
common,
|
||||||
containers,
|
containers,
|
||||||
data-default,
|
data-default,
|
||||||
miso,
|
miso,
|
||||||
neat-interpolation,
|
neat-interpolation,
|
||||||
safe,
|
safe,
|
||||||
|
split,
|
||||||
text,
|
text,
|
||||||
utf8-string
|
utf8-string
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"json2sql": {
|
"json2sql": {
|
||||||
"branch": "main",
|
"branch": "main",
|
||||||
"repo": "git@code.nomath.org:~/json2sql",
|
"repo": "git@code.nomath.org:~/json2sql",
|
||||||
"rev": "d8b2af98f594e4fc5cc4919c1efe95e1d8d9aafe",
|
"rev": "906d9ebba1ae08ea73acb55b536ff2f49e1b55c0",
|
||||||
"type": "git"
|
"type": "git"
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
|
|||||||
Reference in New Issue
Block a user