Plan for MassInput-Controls being buttons

This commit is contained in:
Gregor Kleen 2019-01-31 11:43:32 +01:00
parent 7acba967d1
commit e9c69e6cfb
4 changed files with 70 additions and 64 deletions

View File

@ -611,4 +611,6 @@ DeleteConfirmation: Bestätigung
DeleteConfirmationWrong: Bestätigung muss genau dem angezeigten Text entsprechen. DeleteConfirmationWrong: Bestätigung muss genau dem angezeigten Text entsprechen.
DBTIRowsMissing n@Int: #{pluralDE n "Eine Zeile ist" "Einige Zeile sind"} aus der Datenbank verschwunden, seit das Formular für Sie generiert wurde DBTIRowsMissing n@Int: #{pluralDE n "Eine Zeile ist" "Einige Zeile sind"} aus der Datenbank verschwunden, seit das Formular für Sie generiert wurde
MassInputUpdate: Formular aktualisieren
MassInputAddDimension: Hinzufügen
MassInputDeleteCell: Entfernen

View File

@ -1,6 +1,8 @@
module Handler.Utils.Form.MassInput module Handler.Utils.Form.MassInput
( massInput ( massInput
, BoxDimension(..), IsBoxCoord(..), Liveliness(..) , BoxDimension(..)
, IsBoxCoord(..), boxDimension
, Liveliness(..)
) where ) where
import Import import Import
@ -14,15 +16,23 @@ import Control.Lens hiding (universe)
import Text.Blaze (Markup) import Text.Blaze (Markup)
import Data.List ((!!), elemIndex)
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.List (genericLength, genericIndex)
data BoxDimension x = forall n. Enum n => BoxDimension (Lens' x n) data BoxDimension x = forall n. Enum n => BoxDimension (Lens' x n)
class (PathPiece x, ToJSONKey x, FromJSONKey x, Eq x, Ord x) => IsBoxCoord x where class (PathPiece x, ToJSONKey x, FromJSONKey x, Eq x, Ord x) => IsBoxCoord x where
boxDimensions :: [BoxDimension x] boxDimensions :: [BoxDimension x]
boxOrigin :: x boxOrigin :: x
boxDimension :: IsBoxCoord x => Natural -> Maybe (BoxDimension x)
boxDimension n
| n < genericLength dims = Just $ genericIndex dims n
| otherwise = Nothing
where
dims = boxDimensions
class (ToJSON a, FromJSON a, IsBoxCoord (BoxCoord a), Lattice a, BoundedJoinSemiLattice a) => Liveliness a where class (ToJSON a, FromJSON a, IsBoxCoord (BoxCoord a), Lattice a, BoundedJoinSemiLattice a) => Liveliness a where
type BoxCoord a :: * type BoxCoord a :: *
@ -30,75 +40,55 @@ class (ToJSON a, FromJSON a, IsBoxCoord (BoxCoord a), Lattice a, BoundedJoinSemi
liveCoord :: BoxCoord a -> Prism' Bool a liveCoord :: BoxCoord a -> Prism' Bool a
data MassInputButton submit data ButtonMassInput coord
= MassInputUpdate
| MassInputSubmit submit
deriving (Eq, Ord, Read, Show, Generic, Typeable)
instance Bounded submit => Bounded (MassInputButton submit) where
minBound = MassInputUpdate
maxBound = MassInputSubmit maxBound
instance (Eq submit, Finite submit) => Enum (MassInputButton submit) where
toEnum = (!!) universe
fromEnum = fromMaybe (error "fromEnum: value not found") . flip elemIndex universeF
instance Finite submit => Universe (MassInputButton submit) where
universe = MassInputUpdate : map MassInputSubmit universeF
instance Finite submit => Finite (MassInputButton submit)
instance PathPiece submit => PathPiece (MassInputButton submit) where
toPathPiece = \case
MassInputUpdate -> "update"
MassInputSubmit s -> "submit__" <> toPathPiece s
fromPathPiece t = inpUpdate <|> submit
where
inpUpdate = MassInputUpdate <$ guard (t == "update")
submit = do
submitT <- stripPrefix "submit__" t
MassInputSubmit <$> fromPathPiece submitT
instance (Button UniWorX submit, Finite submit) => Button UniWorX (MassInputButton submit) where
label MassInputUpdate = [whamlet|_{MsgMassInputUpdate}|]
label (MassInputSubmit submit) = label submit
btnValidate _ MassInputUpdate = False
btnValidate proxy (MassInputSubmit submit) = btnValidate proxy submit
cssClass MassInputUpdate = BCDefault
cssClass (MassInputSubmit submit) = cssClass submit
data MassInputFieldName x
= MassInputAddDimension Natural = MassInputAddDimension Natural
| MassInputDeleteCell x | MassInputDeleteCell coord
| MassInputCell x Text
deriving (Eq, Ord, Read, Show, Generic, Typeable) deriving (Eq, Ord, Read, Show, Generic, Typeable)
instance IsBoxCoord x => PathPiece (MassInputFieldName x) where instance PathPiece coord => PathPiece (ButtonMassInput coord) where
toPathPiece = \case
MassInputAddDimension n -> "add__" <> toPathPiece n
MassInputDeleteCell c -> "delete__" <> toPathPiece c
fromPathPiece t = addDim <|> delCell
where
addDim = do
nT <- stripPrefix "add__" t
MassInputAddDimension <$> fromPathPiece nT
delCell = do
coordT <- stripPrefix "delete__" t
MassInputDeleteCell <$> fromPathPiece coordT
instance RenderMessage UniWorX (ButtonMassInput coord) where
renderMessage f ls = \case
MassInputAddDimension _ -> mr MsgMassInputAddDimension
MassInputDeleteCell _ -> mr MsgMassInputDeleteCell
where
mr = renderMessage f ls
instance PathPiece coord => Button UniWorX (ButtonMassInput coord) where
btnValidate _ _ = False
btnClasses (MassInputAddDimension _) = [BCIsButton, BCDefault]
btnClasses (MassInputDeleteCell _) = [BCIsButton, BCWarning]
data MassInputFieldName coord
= MassInputCell coord Text
deriving (Eq, Ord, Read, Show, Generic, Typeable)
instance IsBoxCoord coord => PathPiece (MassInputFieldName coord) where
toPathPiece = \case toPathPiece = \case
MassInputAddDimension dim -> "addField--" <> tshow dim
MassInputDeleteCell (toPathPiece -> coord) -> "delCell--" <> coord
MassInputCell (toPathPiece -> coord) name -> coord <> "__" <> name MassInputCell (toPathPiece -> coord) name -> coord <> "__" <> name
fromPathPiece t = addDimension <|> deleteCell <|> cell fromPathPiece t = do
where (coordT, Text.stripPrefix "__" -> Just name) <- return $ Text.breakOn "__" t
addDimension = do coord <- fromPathPiece coordT
dim <- Text.stripPrefix "addField--" t >>= readMay return $ MassInputCell coord name
return $ MassInputAddDimension dim
deleteCell = do
coord <- Text.stripPrefix "delCell--" t >>= fromPathPiece
return $ MassInputDeleteCell coord
cell = do
(coordT, Text.stripPrefix "__" -> Just name) <- return $ Text.breakOn "__" t
coord <- fromPathPiece coordT
return $ MassInputCell coord name
massInput :: forall handler cellData cellResult liveliness submit p. massInput :: forall handler cellData cellResult liveliness.
( MonadHandler handler, HandlerSite handler ~ UniWorX ( MonadHandler handler, HandlerSite handler ~ UniWorX
, ToJSON cellData, FromJSON cellData , ToJSON cellData, FromJSON cellData
, Liveliness liveliness , Liveliness liveliness
, Button UniWorX submit, Finite submit
) )
=> ( Natural -- ^ Zero-based dimension index => ( Natural -- ^ Zero-based dimension index
-> liveliness -- ^ Currently live positions -> liveliness -- ^ Currently live positions
@ -111,7 +101,6 @@ massInput :: forall handler cellData cellResult liveliness submit p.
-> (Markup -> MForm handler (FormResult cellResult, Widget)) -> (Markup -> MForm handler (FormResult cellResult, Widget))
) -- ^ Cell-Widget ) -- ^ Cell-Widget
-> FieldSettings UniWorX -> FieldSettings UniWorX
-> p submit
-> MForm handler (FormResult (Map (BoxCoord liveliness) cellResult), FieldView UniWorX) -> MForm handler (FormResult (Map (BoxCoord liveliness) cellResult), FieldView UniWorX)
massInput mkAddWidget mkCellWidget FieldSettings{..} _ = do massInput mkAddWidget mkCellWidget FieldSettings{..} = do
error "massInput: not implemented" error "massInput: not implemented"

View File

@ -61,6 +61,8 @@ import Database.Esqueleto.Instances as Import ()
import Database.Persist.Sql.Instances as Import () import Database.Persist.Sql.Instances as Import ()
import Database.Persist.Sql as Import (SqlReadT,SqlWriteT) import Database.Persist.Sql as Import (SqlReadT,SqlWriteT)
import Numeric.Natural.Instances as Import ()
import Control.Monad.Trans.RWS (RWST) import Control.Monad.Trans.RWS (RWST)

View File

@ -0,0 +1,13 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Numeric.Natural.Instances
(
) where
import ClassyPrelude
import Numeric.Natural
import Web.PathPieces
instance PathPiece Natural where
toPathPiece = tshow
fromPathPiece = readMay