module Page.EditValue ( Model, initialModel, Action, updateModel, viewModel, ) where import ACMS.API.REST.Collection qualified as API.REST.Collection import Control.Monad.Catch (SomeException, try) import Data.Aeson qualified as A import Data.Aeson.KeyMap qualified as AM import Data.ByteString.Lazy.UTF8 qualified as LB import Data.Maybe import Effect (Eff) import Form qualified as F import Miso import Miso.String (toMisoString) import Safe (headMay) import Schema import Collection data Model = Model { collectionItem :: CollectionItem, input :: Maybe A.Object, schema :: Schema } deriving (Show, Eq) initialModel :: CollectionItem -> JSM (Either SomeException Model) initialModel collectionItem = do schema' <- try (API.REST.Collection.schema collectionItem.collection) input' <- try (headMay <$> API.REST.Collection.read collectionItem) pure do schema <- schema' input <- input' pure $ Model {..} newtype Action = Action (Model -> (Effect Action Model, [Eff])) update__formChanged :: A.Object -> Action update__formChanged (Just -> input) = Action $ \m -> (noEff m {input}, []) update__formSubmitted :: A.Object -> Action update__formSubmitted output = Action $ \m -> (m <# do update__entityWritten <$> try (API.REST.Collection.update m.collectionItem output), []) update__entityWritten :: Either SomeException A.Object -> Action update__entityWritten _ = Action $ \m -> (noEff m, []) updateModel :: Action -> Model -> (Effect Action Model, [Eff]) updateModel (Action f) m = f m viewModel :: Model -> View Action viewModel m = do let input = (fromMaybe AM.empty m.input) div_ [] $ [ viewForm input m.schema, viewInput input, viewOutput input m.schema ] viewForm :: A.Object -> Schema -> View Action viewForm input = fmap (either update__formChanged update__formSubmitted) . flip F.runForm input . schemaForm viewInput :: A.Object -> View Action viewInput input = pre_ [] [text (toMisoString (A.encode input))] viewOutput :: A.Object -> Schema -> View Action viewOutput input schema = pre_ [] $ [ text $ either ("Left " <>) (("Right " <>)) $ (toMisoString . A.encode <$> ((schemaForm schema).fill input)) ]