From 27e11b20b06f2f2dbfb56c0998a63169b4b8abc4 Mon Sep 17 00:00:00 2001 From: Joris Date: Wed, 8 Nov 2017 23:47:26 +0100 Subject: Use a better project structure --- client/src/Component/Input.hs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 client/src/Component/Input.hs (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs new file mode 100644 index 0000000..7111630 --- /dev/null +++ b/client/src/Component/Input.hs @@ -0,0 +1,34 @@ +{-# LANGUAGE ExistentialQuantification #-} +{-# LANGUAGE OverloadedStrings #-} + +module Component.Input + ( InputIn(..) + , InputOut(..) + , input + ) where + +import Data.Text (Text) +import Reflex.Dom (MonadWidget, Dynamic, Event, (&), (.~), (=:)) +import qualified Reflex.Dom as R + +data InputIn t a b = InputIn + { _inputIn_reset :: Event t a + , _inputIn_placeHolder :: Text + } + +data InputOut t = InputOut + { _inputOut_value :: Dynamic t Text + , _inputOut_enter :: Event t () + } + +input :: forall t m a b. MonadWidget t m => InputIn t a b -> m (InputOut t) +input inputIn = do + let placeHolder = R.constDyn ("placeHolder" =: _inputIn_placeHolder inputIn) + let value = fmap (const "") (_inputIn_reset inputIn) + textInput <- R.textInput $ R.def & R.attributes .~ placeHolder + & R.setValue .~ value + let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput + return $ InputOut + { _inputOut_value = R._textInput_value textInput + , _inputOut_enter = enter + } -- cgit v1.2.3 From 5a63f7be9375e3ab888e4232dd7ef72c2f1ffae1 Mon Sep 17 00:00:00 2001 From: Joris Date: Mon, 13 Nov 2017 23:56:40 +0100 Subject: Setup stylish-haskell --- client/src/Component/Input.hs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 7111630..c3864b4 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -1,5 +1,4 @@ -{-# LANGUAGE ExistentialQuantification #-} -{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE OverloadedStrings #-} module Component.Input ( InputIn(..) @@ -7,12 +6,12 @@ module Component.Input , input ) where -import Data.Text (Text) -import Reflex.Dom (MonadWidget, Dynamic, Event, (&), (.~), (=:)) +import Data.Text (Text) +import Reflex.Dom (Dynamic, Event, MonadWidget, (&), (.~), (=:)) import qualified Reflex.Dom as R data InputIn t a b = InputIn - { _inputIn_reset :: Event t a + { _inputIn_reset :: Event t a , _inputIn_placeHolder :: Text } -- cgit v1.2.3 From 7194cddb28656c721342c2ef604f9f9fb0692960 Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 19 Nov 2017 00:20:25 +0100 Subject: Show payment count and partition - Also fixes exceedingPayer in back by using only punctual payments --- client/src/Component/Input.hs | 2 -- 1 file changed, 2 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index c3864b4..1923463 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE OverloadedStrings #-} - module Component.Input ( InputIn(..) , InputOut(..) -- cgit v1.2.3 From 49426740e8e0c59040f4f3721a658f225572582b Mon Sep 17 00:00:00 2001 From: Joris Date: Tue, 28 Nov 2017 09:11:19 +0100 Subject: Add search for payments --- client/src/Component/Input.hs | 57 +++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 1923463..7eec7d0 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -4,13 +4,19 @@ module Component.Input , input ) where -import Data.Text (Text) -import Reflex.Dom (Dynamic, Event, MonadWidget, (&), (.~), (=:)) -import qualified Reflex.Dom as R +import qualified Data.Map as M +import Data.Text (Text) +import qualified Data.Text as T +import Reflex.Dom (Dynamic, Event, MonadWidget, (&), (.~)) +import qualified Reflex.Dom as R + +import Component.Button (ButtonIn (..), ButtonOut (..)) +import qualified Component.Button as Button +import qualified Icon data InputIn t a b = InputIn - { _inputIn_reset :: Event t a - , _inputIn_placeHolder :: Text + { _inputIn_reset :: Event t a + , _inputIn_label :: Text } data InputOut t = InputOut @@ -19,13 +25,34 @@ data InputOut t = InputOut } input :: forall t m a b. MonadWidget t m => InputIn t a b -> m (InputOut t) -input inputIn = do - let placeHolder = R.constDyn ("placeHolder" =: _inputIn_placeHolder inputIn) - let value = fmap (const "") (_inputIn_reset inputIn) - textInput <- R.textInput $ R.def & R.attributes .~ placeHolder - & R.setValue .~ value - let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput - return $ InputOut - { _inputOut_value = R._textInput_value textInput - , _inputOut_enter = enter - } +input inputIn = + R.divClass "textInput" $ do + rec + let resetValue = R.leftmost + [ fmap (const "") (_inputIn_reset inputIn) + , fmap (const "") (_buttonOut_clic reset) + ] + + attributes = R.ffor value (\v -> + if T.null v then M.empty else M.singleton "class" "filled") + + value = R._textInput_value textInput + + textInput <- R.textInput $ R.def + & R.attributes .~ attributes + & R.setValue .~ resetValue + + R.el "label" $ R.text (_inputIn_label inputIn) + + reset <- Button.button $ ButtonIn + { _buttonIn_class = R.constDyn "" + , _buttonIn_content = Icon.cross + , _buttonIn_waiting = R.never + } + + let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput + + return $ InputOut + { _inputOut_value = value + , _inputOut_enter = enter + } -- cgit v1.2.3 From a4acc2e84158fa822f88a1d0bdddb470708b5809 Mon Sep 17 00:00:00 2001 From: Joris Date: Wed, 3 Jan 2018 17:31:20 +0100 Subject: Modify weelky report and payment search interface - Add payment balance in weekly report - Show a message and hide pages when the search results in no results - Go to page 1 when the search is updated / erased --- client/src/Component/Input.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 7eec7d0..24aac22 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -45,7 +45,7 @@ input inputIn = R.el "label" $ R.text (_inputIn_label inputIn) reset <- Button.button $ ButtonIn - { _buttonIn_class = R.constDyn "" + { _buttonIn_class = R.constDyn "reset" , _buttonIn_content = Icon.cross , _buttonIn_waiting = R.never } -- cgit v1.2.3 From 33b85b7f12798f5762d940ed5c30f775cdd7b751 Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 28 Jan 2018 12:13:09 +0100 Subject: WIP --- client/src/Component/Input.hs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 24aac22..92f8ec9 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -2,12 +2,14 @@ module Component.Input ( InputIn(..) , InputOut(..) , input + , defaultInputIn ) where import qualified Data.Map as M import Data.Text (Text) import qualified Data.Text as T -import Reflex.Dom (Dynamic, Event, MonadWidget, (&), (.~)) +import Reflex.Dom (Dynamic, Event, MonadWidget, Reflex, (&), + (.~)) import qualified Reflex.Dom as R import Component.Button (ButtonIn (..), ButtonOut (..)) @@ -15,8 +17,16 @@ import qualified Component.Button as Button import qualified Icon data InputIn t a b = InputIn - { _inputIn_reset :: Event t a - , _inputIn_label :: Text + { _inputIn_reset :: Event t a + , _inputIn_label :: Text + , _inputIn_initialValue :: Text + } + +defaultInputIn :: (Reflex t) => InputIn t a b +defaultInputIn = InputIn + { _inputIn_reset = R.never + , _inputIn_label = "" + , _inputIn_initialValue = "" } data InputOut t = InputOut @@ -41,14 +51,15 @@ input inputIn = textInput <- R.textInput $ R.def & R.attributes .~ attributes & R.setValue .~ resetValue + & R.textInputConfig_initialValue .~ (_inputIn_initialValue inputIn) R.el "label" $ R.text (_inputIn_label inputIn) - reset <- Button.button $ ButtonIn - { _buttonIn_class = R.constDyn "reset" - , _buttonIn_content = Icon.cross - , _buttonIn_waiting = R.never - } + reset <- Button.button $ + (Button.defaultButtonIn Icon.cross) + { _buttonIn_class = R.constDyn "reset" + , _buttonIn_tabIndex = Just (-1) + } let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput -- cgit v1.2.3 From df83b634006c699cfa1e921bf74ce951a906a62f Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 24 Jun 2018 22:02:00 +0200 Subject: Use date input type --- client/src/Component/Input.hs | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 92f8ec9..c1eb4e8 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -17,16 +17,20 @@ import qualified Component.Button as Button import qualified Icon data InputIn t a b = InputIn - { _inputIn_reset :: Event t a - , _inputIn_label :: Text - , _inputIn_initialValue :: Text + { _inputIn_reset :: Event t a + , _inputIn_hasResetButton :: Bool + , _inputIn_label :: Text + , _inputIn_initialValue :: Text + , _inputIn_inputType :: Text } defaultInputIn :: (Reflex t) => InputIn t a b defaultInputIn = InputIn - { _inputIn_reset = R.never - , _inputIn_label = "" - , _inputIn_initialValue = "" + { _inputIn_reset = R.never + , _inputIn_hasResetButton = True + , _inputIn_label = "" + , _inputIn_initialValue = "" + , _inputIn_inputType = "text" } data InputOut t = InputOut @@ -40,11 +44,13 @@ input inputIn = rec let resetValue = R.leftmost [ fmap (const "") (_inputIn_reset inputIn) - , fmap (const "") (_buttonOut_clic reset) + , fmap (const "") resetClic ] attributes = R.ffor value (\v -> - if T.null v then M.empty else M.singleton "class" "filled") + if T.null v && _inputIn_inputType inputIn /= "date" + then M.empty + else M.singleton "class" "filled") value = R._textInput_value textInput @@ -52,14 +58,20 @@ input inputIn = & R.attributes .~ attributes & R.setValue .~ resetValue & R.textInputConfig_initialValue .~ (_inputIn_initialValue inputIn) + & R.textInputConfig_inputType .~ (_inputIn_inputType inputIn) R.el "label" $ R.text (_inputIn_label inputIn) - reset <- Button.button $ - (Button.defaultButtonIn Icon.cross) - { _buttonIn_class = R.constDyn "reset" - , _buttonIn_tabIndex = Just (-1) - } + resetClic <- + if _inputIn_hasResetButton inputIn + then + _buttonOut_clic <$> (Button.button $ + (Button.defaultButtonIn Icon.cross) + { _buttonIn_class = R.constDyn "reset" + , _buttonIn_tabIndex = Just (-1) + }) + else + return R.never let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput -- cgit v1.2.3 From 50fb8fa48d1c4881da20b4ecf6d68a772301e713 Mon Sep 17 00:00:00 2001 From: Joris Date: Tue, 30 Oct 2018 18:04:58 +0100 Subject: Update table when adding or removing a payment --- client/src/Component/Input.hs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index c1eb4e8..57018a6 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -16,18 +16,16 @@ import Component.Button (ButtonIn (..), ButtonOut (..)) import qualified Component.Button as Button import qualified Icon -data InputIn t a b = InputIn - { _inputIn_reset :: Event t a - , _inputIn_hasResetButton :: Bool +data InputIn = InputIn + { _inputIn_hasResetButton :: Bool , _inputIn_label :: Text , _inputIn_initialValue :: Text , _inputIn_inputType :: Text } -defaultInputIn :: (Reflex t) => InputIn t a b +defaultInputIn :: InputIn defaultInputIn = InputIn - { _inputIn_reset = R.never - , _inputIn_hasResetButton = True + { _inputIn_hasResetButton = True , _inputIn_label = "" , _inputIn_initialValue = "" , _inputIn_inputType = "text" @@ -38,12 +36,16 @@ data InputOut t = InputOut , _inputOut_enter :: Event t () } -input :: forall t m a b. MonadWidget t m => InputIn t a b -> m (InputOut t) -input inputIn = +input + :: forall t m a b. MonadWidget t m + => InputIn + -> Event t a -- reset + -> m (InputOut t) +input inputIn reset = R.divClass "textInput" $ do rec let resetValue = R.leftmost - [ fmap (const "") (_inputIn_reset inputIn) + [ fmap (const "") reset , fmap (const "") resetClic ] -- cgit v1.2.3 From 2741f47ef7b87255203bc2f7f7b2b9140c70b8f0 Mon Sep 17 00:00:00 2001 From: Joris Date: Thu, 1 Nov 2018 13:14:25 +0100 Subject: Implementing client side validation --- client/src/Component/Input.hs | 114 +++++++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 36 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 57018a6..67f97c0 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -5,59 +5,91 @@ module Component.Input , defaultInputIn ) where -import qualified Data.Map as M -import Data.Text (Text) -import qualified Data.Text as T -import Reflex.Dom (Dynamic, Event, MonadWidget, Reflex, (&), - (.~)) -import qualified Reflex.Dom as R - -import Component.Button (ButtonIn (..), ButtonOut (..)) -import qualified Component.Button as Button +import qualified Data.Map as M +import qualified Data.Maybe as Maybe +import Data.Text (Text) +import qualified Data.Text as T +import Data.Time (NominalDiffTime) +import Data.Validation (Validation (Failure, Success)) +import qualified Data.Validation as V +import Reflex.Dom (Dynamic, Event, MonadWidget, Reflex, + (&), (.~)) +import qualified Reflex.Dom as R + +import qualified Common.Util.Validation as ValidationUtil +import Component.Button (ButtonIn (..), ButtonOut (..)) +import qualified Component.Button as Button import qualified Icon -data InputIn = InputIn +data InputIn a = InputIn { _inputIn_hasResetButton :: Bool , _inputIn_label :: Text , _inputIn_initialValue :: Text , _inputIn_inputType :: Text + , _inputIn_validation :: Text -> Validation Text a } -defaultInputIn :: InputIn +defaultInputIn :: InputIn Text defaultInputIn = InputIn { _inputIn_hasResetButton = True , _inputIn_label = "" , _inputIn_initialValue = "" , _inputIn_inputType = "text" + , _inputIn_validation = V.Success } -data InputOut t = InputOut - { _inputOut_value :: Dynamic t Text +data InputOut t a = InputOut + { _inputOut_raw :: Dynamic t Text + , _inputOut_value :: Dynamic t (Maybe (Validation Text a)) , _inputOut_enter :: Event t () } input :: forall t m a b. MonadWidget t m - => InputIn - -> Event t a -- reset - -> m (InputOut t) -input inputIn reset = - R.divClass "textInput" $ do - rec - let resetValue = R.leftmost - [ fmap (const "") reset - , fmap (const "") resetClic - ] - - attributes = R.ffor value (\v -> - if T.null v && _inputIn_inputType inputIn /= "date" - then M.empty - else M.singleton "class" "filled") - - value = R._textInput_value textInput + => InputIn a + -> Event t Text -- reset + -> Event t b -- validate + -> m (InputOut t a) +input inputIn reset validate = do + rec + let resetValue = R.leftmost + [ R.traceEvent "reset" reset + , fmap (const "") resetClic + ] + + inputAttr = R.ffor value (\v -> + if T.null v && _inputIn_inputType inputIn /= "date" + then M.empty + else M.singleton "class" "filled") + + value = R._textInput_value textInput + + containerAttr = R.ffor validatedValue (\v -> + M.singleton "class" $ T.intercalate " " + [ "textInput" + , if Maybe.fromMaybe False (ValidationUtil.isFailure <$> v) then "error" else "" + ]) + + -- Clear validation errors after reset + delayedReset <- R.delay (0.1 :: NominalDiffTime) reset + + validatedValue <- R.holdDyn Nothing $ R.attachWith + (\v (clearValidation, validateEmpty) -> + if clearValidation + then Nothing + else Just (_inputIn_validation inputIn $ (if validateEmpty then "" else v))) + (R.current value) + (R.leftmost + [ const (False, True) <$> resetClic + , (\f -> (f, False)) <$> (R.updated . R._textInput_hasFocus $ textInput) + , const (False, False) <$> validate + , const (True, False) <$> R.traceEvent "delayedReset" delayedReset + ]) + + (textInput, resetClic) <- R.elDynAttr "div" containerAttr $ do textInput <- R.textInput $ R.def - & R.attributes .~ attributes + & R.attributes .~ inputAttr & R.setValue .~ resetValue & R.textInputConfig_initialValue .~ (_inputIn_initialValue inputIn) & R.textInputConfig_inputType .~ (_inputIn_inputType inputIn) @@ -75,9 +107,19 @@ input inputIn reset = else return R.never - let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput + R.divClass "errorMessage" $ + R.dynText . fmap validationError $ validatedValue + + return (textInput, resetClic) + + let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput + + return $ InputOut + { _inputOut_raw = value + , _inputOut_value = validatedValue + , _inputOut_enter = enter + } - return $ InputOut - { _inputOut_value = value - , _inputOut_enter = enter - } +validationError :: Maybe (Validation Text a) -> Text +validationError (Just (Failure e)) = e +validationError _ = "" -- cgit v1.2.3 From bc81084933f8ec1bfe6c2834defd12243117fdd9 Mon Sep 17 00:00:00 2001 From: Joris Date: Mon, 5 Aug 2019 21:53:30 +0200 Subject: Use updated payment categories from payment add in payment’s table --- client/src/Component/Input.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 67f97c0..d679f9b 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -53,7 +53,7 @@ input input inputIn reset validate = do rec let resetValue = R.leftmost - [ R.traceEvent "reset" reset + [ reset , fmap (const "") resetClic ] @@ -83,7 +83,7 @@ input inputIn reset validate = do [ const (False, True) <$> resetClic , (\f -> (f, False)) <$> (R.updated . R._textInput_hasFocus $ textInput) , const (False, False) <$> validate - , const (True, False) <$> R.traceEvent "delayedReset" delayedReset + , const (True, False) <$> delayedReset ]) (textInput, resetClic) <- R.elDynAttr "div" containerAttr $ do -- cgit v1.2.3 From 7c77e52faa71e43324087903c905f9d493b1dfb7 Mon Sep 17 00:00:00 2001 From: Joris Date: Thu, 8 Aug 2019 21:28:22 +0200 Subject: Finish payment add modal --- client/src/Component/Input.hs | 69 ++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 23 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index d679f9b..abdc51c 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -40,7 +40,7 @@ defaultInputIn = InputIn data InputOut t a = InputOut { _inputOut_raw :: Dynamic t Text - , _inputOut_value :: Dynamic t (Maybe (Validation Text a)) + , _inputOut_value :: Dynamic t (Validation Text a) , _inputOut_enter :: Event t () } @@ -64,27 +64,14 @@ input inputIn reset validate = do value = R._textInput_value textInput - containerAttr = R.ffor validatedValue (\v -> + containerAttr = R.ffor inputError (\e -> M.singleton "class" $ T.intercalate " " [ "textInput" - , if Maybe.fromMaybe False (ValidationUtil.isFailure <$> v) then "error" else "" + , if Maybe.isJust e then "error" else "" ]) - -- Clear validation errors after reset - delayedReset <- R.delay (0.1 :: NominalDiffTime) reset - - validatedValue <- R.holdDyn Nothing $ R.attachWith - (\v (clearValidation, validateEmpty) -> - if clearValidation - then Nothing - else Just (_inputIn_validation inputIn $ (if validateEmpty then "" else v))) - (R.current value) - (R.leftmost - [ const (False, True) <$> resetClic - , (\f -> (f, False)) <$> (R.updated . R._textInput_hasFocus $ textInput) - , const (False, False) <$> validate - , const (True, False) <$> delayedReset - ]) + let valueWithValidation = R.ffor value (\v -> (v, _inputIn_validation inputIn $ v)) + inputError <- getInputError valueWithValidation validate (textInput, resetClic) <- R.elDynAttr "div" containerAttr $ do @@ -108,7 +95,7 @@ input inputIn reset validate = do return R.never R.divClass "errorMessage" $ - R.dynText . fmap validationError $ validatedValue + R.dynText . fmap (Maybe.fromMaybe "") $ inputError return (textInput, resetClic) @@ -116,10 +103,46 @@ input inputIn reset validate = do return $ InputOut { _inputOut_raw = value - , _inputOut_value = validatedValue + , _inputOut_value = fmap snd valueWithValidation , _inputOut_enter = enter } -validationError :: Maybe (Validation Text a) -> Text -validationError (Just (Failure e)) = e -validationError _ = "" +getInputError + :: forall t m a b c. MonadWidget t m + => Dynamic t (Text, Validation Text a) + -> Event t c + -> m (Dynamic t (Maybe Text)) +getInputError validatedValue validate = do + let errorDynamic = fmap (\(t, v) -> (t, validationError v)) validatedValue + errorEvent = R.updated errorDynamic + delayedError <- R.debounce (1 :: NominalDiffTime) errorEvent + fmap (fmap fst) $ R.foldDyn + (\event (err, hasBeenResetted) -> + case event of + ModifiedEvent t -> + (Nothing, T.null t) + + ValidateEvent e -> + (e, False) + + DelayEvent e -> + if hasBeenResetted then + (Nothing, False) + else + (e, False) + ) + (Nothing, False) + (R.leftmost + [ fmap (\(t, _) -> ModifiedEvent t) errorEvent + , fmap (\(_, e) -> DelayEvent e) delayedError + , R.attachWith (\(_, e) _ -> ValidateEvent e) (R.current errorDynamic) validate + ]) + +validationError :: (Validation Text a) -> Maybe Text +validationError (Failure e) = Just e +validationError _ = Nothing + +data InputEvent + = ModifiedEvent Text + | DelayEvent (Maybe Text) + | ValidateEvent (Maybe Text) -- cgit v1.2.3 From 2cbd43c3a0f0640776a4e7c7425b3210d2e6632b Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 6 Oct 2019 19:41:17 +0200 Subject: Make input label clickable again --- client/src/Component/Input.hs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index abdc51c..0c84754 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -75,13 +75,17 @@ input inputIn reset validate = do (textInput, resetClic) <- R.elDynAttr "div" containerAttr $ do - textInput <- R.textInput $ R.def - & R.attributes .~ inputAttr - & R.setValue .~ resetValue - & R.textInputConfig_initialValue .~ (_inputIn_initialValue inputIn) - & R.textInputConfig_inputType .~ (_inputIn_inputType inputIn) + textInput <- R.el "label" $ do + textInput <- R.textInput $ R.def + & R.attributes .~ inputAttr + & R.setValue .~ resetValue + & R.textInputConfig_initialValue .~ (_inputIn_initialValue inputIn) + & R.textInputConfig_inputType .~ (_inputIn_inputType inputIn) - R.el "label" $ R.text (_inputIn_label inputIn) + R.divClass "label" $ + R.text (_inputIn_label inputIn) + + return textInput resetClic <- if _inputIn_hasResetButton inputIn -- cgit v1.2.3 From 33e78f2ebbf5bf7b40e7aa732cc7c019f6df3f12 Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 20 Oct 2019 22:08:31 +0200 Subject: Simplify page initialization --- client/src/Component/Input.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 0c84754..9ab4d58 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -19,7 +19,7 @@ import qualified Reflex.Dom as R import qualified Common.Util.Validation as ValidationUtil import Component.Button (ButtonIn (..), ButtonOut (..)) import qualified Component.Button as Button -import qualified Icon +import qualified View.Icon as Icon data InputIn a = InputIn { _inputIn_hasResetButton :: Bool -- cgit v1.2.3 From 613ffccac4b3ab25c6d4c631fab757da0b35acf6 Mon Sep 17 00:00:00 2001 From: Joris Date: Tue, 22 Oct 2019 22:26:38 +0200 Subject: Harmonize view component code style --- client/src/Component/Input.hs | 79 +++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 9ab4d58..37020da 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -1,8 +1,8 @@ module Component.Input - ( InputIn(..) - , InputOut(..) - , input - , defaultInputIn + ( In(..) + , Out(..) + , view + , defaultIn ) where import qualified Data.Map as M @@ -17,40 +17,39 @@ import Reflex.Dom (Dynamic, Event, MonadWidget, Reflex, import qualified Reflex.Dom as R import qualified Common.Util.Validation as ValidationUtil -import Component.Button (ButtonIn (..), ButtonOut (..)) import qualified Component.Button as Button import qualified View.Icon as Icon -data InputIn a = InputIn - { _inputIn_hasResetButton :: Bool - , _inputIn_label :: Text - , _inputIn_initialValue :: Text - , _inputIn_inputType :: Text - , _inputIn_validation :: Text -> Validation Text a +data In a = In + { _in_hasResetButton :: Bool + , _in_label :: Text + , _in_initialValue :: Text + , _in_inputType :: Text + , _in_validation :: Text -> Validation Text a } -defaultInputIn :: InputIn Text -defaultInputIn = InputIn - { _inputIn_hasResetButton = True - , _inputIn_label = "" - , _inputIn_initialValue = "" - , _inputIn_inputType = "text" - , _inputIn_validation = V.Success +defaultIn :: In Text +defaultIn = In + { _in_hasResetButton = True + , _in_label = "" + , _in_initialValue = "" + , _in_inputType = "text" + , _in_validation = V.Success } -data InputOut t a = InputOut - { _inputOut_raw :: Dynamic t Text - , _inputOut_value :: Dynamic t (Validation Text a) - , _inputOut_enter :: Event t () +data Out t a = Out + { _out_raw :: Dynamic t Text + , _out_value :: Dynamic t (Validation Text a) + , _out_enter :: Event t () } -input +view :: forall t m a b. MonadWidget t m - => InputIn a + => In a -> Event t Text -- reset -> Event t b -- validate - -> m (InputOut t a) -input inputIn reset validate = do + -> m (Out t a) +view input reset validate = do rec let resetValue = R.leftmost [ reset @@ -58,7 +57,7 @@ input inputIn reset validate = do ] inputAttr = R.ffor value (\v -> - if T.null v && _inputIn_inputType inputIn /= "date" + if T.null v && _in_inputType input /= "date" then M.empty else M.singleton "class" "filled") @@ -70,7 +69,7 @@ input inputIn reset validate = do , if Maybe.isJust e then "error" else "" ]) - let valueWithValidation = R.ffor value (\v -> (v, _inputIn_validation inputIn $ v)) + let valueWithValidation = R.ffor value (\v -> (v, _in_validation input $ v)) inputError <- getInputError valueWithValidation validate (textInput, resetClic) <- R.elDynAttr "div" containerAttr $ do @@ -79,21 +78,21 @@ input inputIn reset validate = do textInput <- R.textInput $ R.def & R.attributes .~ inputAttr & R.setValue .~ resetValue - & R.textInputConfig_initialValue .~ (_inputIn_initialValue inputIn) - & R.textInputConfig_inputType .~ (_inputIn_inputType inputIn) + & R.textInputConfig_initialValue .~ (_in_initialValue input) + & R.textInputConfig_inputType .~ (_in_inputType input) R.divClass "label" $ - R.text (_inputIn_label inputIn) + R.text (_in_label input) return textInput resetClic <- - if _inputIn_hasResetButton inputIn + if _in_hasResetButton input then - _buttonOut_clic <$> (Button.button $ - (Button.defaultButtonIn Icon.cross) - { _buttonIn_class = R.constDyn "reset" - , _buttonIn_tabIndex = Just (-1) + Button._out_clic <$> (Button.view $ + (Button.defaultIn Icon.cross) + { Button._in_class = R.constDyn "reset" + , Button._in_tabIndex = Just (-1) }) else return R.never @@ -105,10 +104,10 @@ input inputIn reset validate = do let enter = fmap (const ()) $ R.ffilter ((==) 13) . R._textInput_keypress $ textInput - return $ InputOut - { _inputOut_raw = value - , _inputOut_value = fmap snd valueWithValidation - , _inputOut_enter = enter + return $ Out + { _out_raw = value + , _out_value = fmap snd valueWithValidation + , _out_enter = enter } getInputError -- cgit v1.2.3 From da2a0c13aa89705c65fdb9df2f496fb4eea29654 Mon Sep 17 00:00:00 2001 From: Joris Date: Sat, 4 Jan 2020 19:22:45 +0100 Subject: Allow to remove only unused categories --- client/src/Component/Input.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'client/src/Component/Input.hs') diff --git a/client/src/Component/Input.hs b/client/src/Component/Input.hs index 37020da..bcff377 100644 --- a/client/src/Component/Input.hs +++ b/client/src/Component/Input.hs @@ -57,7 +57,7 @@ view input reset validate = do ] inputAttr = R.ffor value (\v -> - if T.null v && _in_inputType input /= "date" + if T.null v && _in_inputType input /= "date" && _in_inputType input /= "color" then M.empty else M.singleton "class" "filled") -- cgit v1.2.3