Commit 0e576c00 authored by arturo's avatar arturo

>>> continue

parent 330a1e40
Pipeline #1929 failed with stage
...@@ -77,6 +77,7 @@ to generate this file without the comments in this block. ...@@ -77,6 +77,7 @@ to generate this file without the comments in this block.
, "spec-discovery" , "spec-discovery"
, "spec-quickcheck" , "spec-quickcheck"
, "strings" , "strings"
, "strings-extra"
, "stringutils" , "stringutils"
, "these" , "these"
, "toestand" , "toestand"
......
...@@ -3,8 +3,8 @@ module Gargantext.Components.Bootstrap ...@@ -3,8 +3,8 @@ module Gargantext.Components.Bootstrap
) where ) where
import Gargantext.Components.Bootstrap.BaseModal(baseModal) as Exports import Gargantext.Components.Bootstrap.BaseModal(baseModal) as Exports
import Gargantext.Components.Bootstrap.Button(button) as Exports
import Gargantext.Components.Bootstrap.Div(div', div_) as Exports import Gargantext.Components.Bootstrap.Div(div', div_) as Exports
import Gargantext.Components.Bootstrap.FormInput(formInput) as Exports import Gargantext.Components.Bootstrap.FormInput(formInput) as Exports
import Gargantext.Components.Bootstrap.FormTextarea(formTextarea) as Exports import Gargantext.Components.Bootstrap.FormTextarea(formTextarea) as Exports
import Gargantext.Components.Bootstrap.Button(button) as Exports
import Gargantext.Components.Bootstrap.Spinner(spinner) as Exports import Gargantext.Components.Bootstrap.Spinner(spinner) as Exports
...@@ -4,32 +4,33 @@ import Gargantext.Prelude ...@@ -4,32 +4,33 @@ import Gargantext.Prelude
import Data.Foldable (elem, intercalate) import Data.Foldable (elem, intercalate)
import Effect (Effect) import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
type Props = type Props =
( callback :: String -> Effect Unit ( callback :: String -> Effect Unit
, value :: String , value :: String
| Options | Options
) )
type Options = type Options =
( status :: String ( status :: ComponentStatus
, className :: String , className :: String
, type :: String , type :: String
, placeholder :: String , placeholder :: String
, size :: String , size :: String
) )
options :: Record Options options :: Record Options
options = options =
{ status: "enabled" { status : Enabled
, className: "" , className : ""
, type: "text" , type : "text"
, placeholder: "" , placeholder : ""
, size: "md" , size : "md"
} }
-- | Structural Component for the Bootstrap input -- | Structural Component for the Bootstrap input
...@@ -57,7 +58,7 @@ component = R.hooksComponent componentName cpt where ...@@ -57,7 +58,7 @@ component = R.hooksComponent componentName cpt where
[ props.className [ props.className
-- BEM classNames -- BEM classNames
, componentName , componentName
, componentName <> "--" <> status , componentName <> "--" <> show status
-- Bootstrap specific classNames -- Bootstrap specific classNames
, bootstrapName , bootstrapName
, bootstrapName <> "-" <> props.size , bootstrapName <> "-" <> props.size
...@@ -70,8 +71,8 @@ component = R.hooksComponent componentName cpt where ...@@ -70,8 +71,8 @@ component = R.hooksComponent componentName cpt where
H.input H.input
{ className { className
, on: { change } , on: { change }
, disabled: elem status [ "disabled" ] , disabled: elem status [ Disabled ]
, readOnly: elem status [ "idled" ] , readOnly: elem status [ Idled ]
, placeholder: props.placeholder , placeholder: props.placeholder
, type: props.type , type: props.type
, autoComplete: "off" , autoComplete: "off"
...@@ -82,11 +83,11 @@ component = R.hooksComponent componentName cpt where ...@@ -82,11 +83,11 @@ component = R.hooksComponent componentName cpt where
-- | * Also directly returns the newly input value -- | * Also directly returns the newly input value
-- | (usage not so different from `targetValue` of ReactBasic) -- | (usage not so different from `targetValue` of ReactBasic)
onChange :: forall event. onChange :: forall event.
String ComponentStatus
-> (String -> Effect Unit) -> (String -> Effect Unit)
-> event -> event
-> Effect Unit -> Effect Unit
onChange status callback event = do onChange status callback event = do
if status == "enabled" if status == Enabled
then callback $ (unsafeCoerce event).target.value then callback $ (unsafeCoerce event).target.value
else pure $ unit else pure unit
...@@ -4,28 +4,29 @@ import Gargantext.Prelude ...@@ -4,28 +4,29 @@ import Gargantext.Prelude
import Data.Foldable (elem, intercalate) import Data.Foldable (elem, intercalate)
import Effect (Effect) import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
type Props = type Props =
( callback :: String -> Effect Unit ( callback :: String -> Effect Unit
, value :: String , value :: String
| Options | Options
) )
type Options = type Options =
( status :: String ( status :: ComponentStatus
, className :: String , className :: String
, placeholder :: String , placeholder :: String
) )
options :: Record Options options :: Record Options
options = options =
{ status: "enabled" { status : Enabled
, className: "" , className : ""
, placeholder: "" , placeholder : ""
} }
-- | Structural Component for the Bootstrap textarea -- | Structural Component for the Bootstrap textarea
...@@ -51,7 +52,7 @@ component = R.hooksComponent componentName cpt where ...@@ -51,7 +52,7 @@ component = R.hooksComponent componentName cpt where
[ props.className [ props.className
-- BEM classNames -- BEM classNames
, componentName , componentName
, componentName <> "--" <> status , componentName <> "--" <> show status
-- Bootstrap specific classNames -- Bootstrap specific classNames
, bootstrapName , bootstrapName
] ]
...@@ -64,8 +65,8 @@ component = R.hooksComponent componentName cpt where ...@@ -64,8 +65,8 @@ component = R.hooksComponent componentName cpt where
H.textarea H.textarea
{ className { className
, on: { change } , on: { change }
, disabled: elem status [ "disabled" ] , disabled: elem status [ Disabled ]
, readOnly: elem status [ "idled" ] , readOnly: elem status [ Idled ]
, placeholder: props.placeholder , placeholder: props.placeholder
, autoComplete: "off" , autoComplete: "off"
} [] } []
...@@ -75,11 +76,11 @@ component = R.hooksComponent componentName cpt where ...@@ -75,11 +76,11 @@ component = R.hooksComponent componentName cpt where
-- | * Also directly returns the newly input value -- | * Also directly returns the newly input value
-- | (usage not so different from `targetValue` of ReactBasic) -- | (usage not so different from `targetValue` of ReactBasic)
onChange :: forall event. onChange :: forall event.
String ComponentStatus
-> (String -> Effect Unit) -> (String -> Effect Unit)
-> event -> event
-> Effect Unit -> Effect Unit
onChange status callback event = do onChange status callback event = do
if status == "enabled" if status == Enabled
then callback $ (unsafeCoerce event).target.value then callback $ (unsafeCoerce event).target.value
else pure $ unit else pure unit
...@@ -6,6 +6,7 @@ import Data.Array (elem) ...@@ -6,6 +6,7 @@ import Data.Array (elem)
import Data.Foldable (intercalate) import Data.Foldable (intercalate)
import Effect (Effect) import Effect (Effect)
import Gargantext.Components.Bootstrap.Spinner (spinner) import Gargantext.Components.Bootstrap.Spinner (spinner)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils ((?)) import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import React.SyntheticEvent as SE import React.SyntheticEvent as SE
...@@ -13,12 +14,12 @@ import Reactix as R ...@@ -13,12 +14,12 @@ import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
type Props = type Props =
( callback :: Unit -> Effect Unit ( callback :: Unit -> Effect Unit
| Options | Options
) )
type Options = type Options =
( status :: String ( status :: ComponentStatus
, size :: String , size :: String
, variant :: String , variant :: String
, type :: String , type :: String
...@@ -28,7 +29,7 @@ type Options = ...@@ -28,7 +29,7 @@ type Options =
options :: Record Options options :: Record Options
options = options =
{ status : "enabled" { status : Enabled
, size : "md" , size : "md"
, variant : "primary" , variant : "primary"
, type : "button" , type : "button"
...@@ -61,7 +62,7 @@ component = R.hooksComponent componentName cpt where ...@@ -61,7 +62,7 @@ component = R.hooksComponent componentName cpt where
[ props.className [ props.className
-- BEM classNames -- BEM classNames
, componentName , componentName
, componentName <> "--" <> status , componentName <> "--" <> show status
-- Bootstrap specific classNames -- Bootstrap specific classNames
, bootstrapName , bootstrapName
, bootstrapName <> "-" <> props.variant , bootstrapName <> "-" <> props.variant
...@@ -78,11 +79,11 @@ component = R.hooksComponent componentName cpt where ...@@ -78,11 +79,11 @@ component = R.hooksComponent componentName cpt where
H.button H.button
{ className { className
, on: { click } , on: { click }
, disabled: elem status [ "disabled", "deferred" ] , disabled: elem status [ Disabled, Deferred ]
, type: props.type , type: props.type
} }
[ R2.if' (status == "deferred") $ [ R2.if' (status == Deferred) $
spinner spinner
{ className: componentName <> "__spinner" { className: componentName <> "__spinner"
} }
...@@ -96,12 +97,12 @@ component = R.hooksComponent componentName cpt where ...@@ -96,12 +97,12 @@ component = R.hooksComponent componentName cpt where
-- | Clicked event will effectively be triggered according to the -- | Clicked event will effectively be triggered according to the
-- | component status props -- | component status props
onClick :: forall event. onClick :: forall event.
String ComponentStatus
-> (Unit -> Effect Unit) -> (Unit -> Effect Unit)
-> SE.SyntheticEvent_ event -> SE.SyntheticEvent_ event
-> Effect Unit -> Effect Unit
onClick status callback event = do onClick status callback event = do
SE.preventDefault event SE.preventDefault event
if status == "enabled" if status == Enabled
then callback unit then callback unit
else pure $ unit else pure unit
module Gargantext.Components.Bootstrap.Types
( ComponentStatus(..)
) where
import Gargantext.Prelude
import Data.Generic.Rep (class Generic)
import Data.Show.Generic (genericShow)
import Data.String.Extra (kebabCase)
-- | Component status based on UI/UX overall expression
-- |
-- | * `Enabled`: default UI/UX behavior
-- | * `Disabled`: main action of the component has been deactivated, and
-- | a UI feedback is showed to the user (eg. a disabled button is now
-- | unclikable, fade color, and disabled CTA feature)
-- | * `Deffered`: main action of the component has been deactivated, but
-- | contrary to a disabled state, the altered UX/UI bears characteristics
-- | of a short-lived state (eg. a button turns to `Deffered`, is now
-- | unclickable but presents a less inoperative style, for example a
-- | spinner is now attached in place of the CTA text)
-- | * `Muted`: on surface the component seems functional, but main action
-- | of the component has been deactivated, yet no UI nor UX feedback is
-- | particularly showed to the user accordingly
-- | * `Idled`: balance between a `Disabled` and `Muted` state, as if the
-- | component has its main feature deactivated, but told with a less
-- | strong UI/UX (eg. a input in a "read-only" mode: UI can be alter to
-- | underline the lack of its main writing feature, but without telling
-- | to the user that the input is per-se inoperative)
data ComponentStatus =
Enabled
| Disabled
| Deferred
| Idled
| Muted
derive instance Generic ComponentStatus _
derive instance Eq ComponentStatus
instance Show ComponentStatus where
show a = kebabCase $ genericShow a
...@@ -19,11 +19,13 @@ import Data.Set as Set ...@@ -19,11 +19,13 @@ import Data.Set as Set
import Data.String as Str import Data.String as Str
import Data.Symbol (SProxy(..)) import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\))
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff, Milliseconds(..), delay, launchAff_)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.Components.App.Data (Boxes) import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Components.Category (rating) import Gargantext.Components.Category (rating)
import Gargantext.Components.Category.Types (Star(..)) import Gargantext.Components.Category.Types (Star(..))
import Gargantext.Components.DocsTable.DocumentFormCreation (documentFormCreation) import Gargantext.Components.DocsTable.DocumentFormCreation (documentFormCreation)
...@@ -39,7 +41,7 @@ import Gargantext.Routes (SessionRoute(NodeAPI)) ...@@ -39,7 +41,7 @@ import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Routes as Routes import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId, get, delete) import Gargantext.Sessions (Session, sessionId, get, delete)
import Gargantext.Types (ListId, NodeID, NodeType(..), OrderBy(..), SidePanelState(..), TabSubType, TabType, TableResult, showTabType') import Gargantext.Types (ListId, NodeID, NodeType(..), OrderBy(..), SidePanelState(..), TabSubType, TabType, TableResult, showTabType')
import Gargantext.Utils (sortWith) import Gargantext.Utils (sortWith, (?))
import Gargantext.Utils.CacheAPI as GUC import Gargantext.Utils.CacheAPI as GUC
import Gargantext.Utils.QueryString (joinQueryStrings, mQueryParam, mQueryParamS, queryParam, queryParamS) import Gargantext.Utils.QueryString (joinQueryStrings, mQueryParam, mQueryParamS, queryParam, queryParamS)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
...@@ -131,13 +133,28 @@ docViewCpt = here.component "docView" cpt where ...@@ -131,13 +133,28 @@ docViewCpt = here.component "docView" cpt where
, params , params
, query , query
} _ = do } _ = do
-- State
cacheState' <- T.useLive T.unequal cacheState cacheState' <- T.useLive T.unequal cacheState
query' <- T.useLive T.unequal query query' <- T.useLive T.unequal query
isDocumentModalVisibleBox <- T.useBox false isDocumentModalVisibleBox <- T.useBox false
onDocumentCreationPending /\ onDocumentCreationPendingBox <-
R2.useBox' false
-- @toggleModalCallback
toggleModal <- pure $ const $ toggleModal <- pure $ const $
T.modify_ not isDocumentModalVisibleBox T.modify_ not isDocumentModalVisibleBox
-- @createDocumentCallback
-- @WIP: remote business for document creation
createDocumentCallback <- pure $ \fdata -> launchAff_ do
liftEffect $ T.write_ true onDocumentCreationPendingBox
delay $ Milliseconds 2000.0
liftEffect $ T.write_ false onDocumentCreationPendingBox
-- Render
pure $ pure $
R.fragment R.fragment
...@@ -187,7 +204,9 @@ docViewCpt = here.component "docView" cpt where ...@@ -187,7 +204,9 @@ docViewCpt = here.component "docView" cpt where
} }
[ [
documentFormCreation documentFormCreation
{} { callback: createDocumentCallback
, status: onDocumentCreationPending ? Deferred $ Enabled
}
] ]
] ]
......
module Gargantext.Components.DocsTable.DocumentFormCreation module Gargantext.Components.DocsTable.DocumentFormCreation
( documentFormCreation ( documentFormCreation
, FormData
) where ) where
import Gargantext.Prelude import Gargantext.Prelude
import DOM.Simple.Console (log, log3) import DOM.Simple.Console (log3)
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Foldable (foldl, intercalate) import Data.Foldable (foldl, intercalate)
import Effect (Effect) import Effect (Effect)
import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap as B
import Gargantext.Hooks.FormValidation (useFormValidation) import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Hooks.FormValidation.Types (VForm) import Gargantext.Hooks.FormValidation (VForm, useFormValidation)
import Gargantext.Hooks.FormValidation.Unboxed as FV import Gargantext.Hooks.FormValidation.Unboxed as FV
import Gargantext.Hooks.StateRecord (useStateRecord) import Gargantext.Hooks.StateRecord (useStateRecord)
import Gargantext.Utils (nbsp, (?)) import Gargantext.Utils (nbsp, (?))
...@@ -18,30 +19,27 @@ import Gargantext.Utils.Reactix as R2 ...@@ -18,30 +19,27 @@ import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Record (merge) import Record (merge)
import Record.Extra (pick)
type Props =
type DocumentFormData = ( callback :: Record FormData -> Effect Unit
( title :: String , status :: ComponentStatus
, source :: String | Options
, authors :: String
, abstract :: String
) )
documentDefaultData :: Record DocumentFormData type Options = ( | FormData )
documentDefaultData =
{ title : "" options :: Record Options
, source : "" options = merge {} defaultData
, authors : ""
, abstract : "" documentFormCreation :: forall r. R2.OptLeaf Options Props r
} documentFormCreation = R2.optLeaf component options
documentFormCreation :: R2.Leaf () component :: R.Component Props
documentFormCreation = R2.leaf documentFormCreationCpt component = R.hooksComponent "documentFormCreation" cpt where
documentFormCreationCpt :: R.Component () cpt props _ = do
documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
cpt _ _ = do
-- Hooks -- Hooks
{ state, setStateKey, bindStateKey } <- useStateRecord documentDefaultData { state, bindStateKey } <- useStateRecord (pick props :: Record FormData)
fv <- useFormValidation fv <- useFormValidation
-- @onSubmit: exec whole form validation and execute callback -- @onSubmit: exec whole form validation and execute callback
...@@ -50,8 +48,8 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where ...@@ -50,8 +48,8 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
result <- fv.try (\_ -> documentFormValidation state) result <- fv.try (\_ -> documentFormValidation state)
case result of case result of
Left err -> log3 "document form error" state err Left err -> log3 "document form validation error" state err
Right _ -> log "ok" Right _ -> props.callback state
-- Render -- Render
pure $ pure $
...@@ -166,7 +164,7 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where ...@@ -166,7 +164,7 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
[ [
B.button B.button
{ callback: \_ -> onSubmit { callback: \_ -> onSubmit
-- , status: props.status == "deferred" ? "deferred" $ "enabled" , status: props.status == Deferred ? Deferred $ Enabled
, variant: "primary" , variant: "primary"
, type: "submit" , type: "submit"
, block: true , block: true
...@@ -175,7 +173,22 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where ...@@ -175,7 +173,22 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
] ]
] ]
documentFormValidation :: Record DocumentFormData -> Effect VForm type FormData =
( title :: String
, source :: String
, authors :: String
, abstract :: String
)
defaultData :: Record FormData
defaultData =
{ title : ""
, source : ""
, authors : ""
, abstract : ""
}
documentFormValidation :: Record FormData -> Effect VForm
documentFormValidation r = foldl append mempty rules documentFormValidation r = foldl append mempty rules
where where
rules = rules =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment