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.
, "spec-discovery"
, "spec-quickcheck"
, "strings"
, "strings-extra"
, "stringutils"
, "these"
, "toestand"
......
......@@ -3,8 +3,8 @@ module Gargantext.Components.Bootstrap
) where
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.FormInput(formInput) 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
......@@ -4,32 +4,33 @@ import Gargantext.Prelude
import Data.Foldable (elem, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce)
type Props =
( callback :: String -> Effect Unit
, value :: String
( callback :: String -> Effect Unit
, value :: String
| Options
)
type Options =
( status :: String
, className :: String
, type :: String
( status :: ComponentStatus
, className :: String
, type :: String
, placeholder :: String
, size :: String
, size :: String
)
options :: Record Options
options =
{ status: "enabled"
, className: ""
, type: "text"
, placeholder: ""
, size: "md"
{ status : Enabled
, className : ""
, type : "text"
, placeholder : ""
, size : "md"
}
-- | Structural Component for the Bootstrap input
......@@ -57,7 +58,7 @@ component = R.hooksComponent componentName cpt where
[ props.className
-- BEM classNames
, componentName
, componentName <> "--" <> status
, componentName <> "--" <> show status
-- Bootstrap specific classNames
, bootstrapName
, bootstrapName <> "-" <> props.size
......@@ -70,8 +71,8 @@ component = R.hooksComponent componentName cpt where
H.input
{ className
, on: { change }
, disabled: elem status [ "disabled" ]
, readOnly: elem status [ "idled" ]
, disabled: elem status [ Disabled ]
, readOnly: elem status [ Idled ]
, placeholder: props.placeholder
, type: props.type
, autoComplete: "off"
......@@ -82,11 +83,11 @@ component = R.hooksComponent componentName cpt where
-- | * Also directly returns the newly input value
-- | (usage not so different from `targetValue` of ReactBasic)
onChange :: forall event.
String
ComponentStatus
-> (String -> Effect Unit)
-> event
-> Effect Unit
onChange status callback event = do
if status == "enabled"
if status == Enabled
then callback $ (unsafeCoerce event).target.value
else pure $ unit
else pure unit
......@@ -4,28 +4,29 @@ import Gargantext.Prelude
import Data.Foldable (elem, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce)
type Props =
( callback :: String -> Effect Unit
, value :: String
( callback :: String -> Effect Unit
, value :: String
| Options
)
type Options =
( status :: String
, className :: String
, placeholder :: String
( status :: ComponentStatus
, className :: String
, placeholder :: String
)
options :: Record Options
options =
{ status: "enabled"
, className: ""
, placeholder: ""
{ status : Enabled
, className : ""
, placeholder : ""
}
-- | Structural Component for the Bootstrap textarea
......@@ -51,7 +52,7 @@ component = R.hooksComponent componentName cpt where
[ props.className
-- BEM classNames
, componentName
, componentName <> "--" <> status
, componentName <> "--" <> show status
-- Bootstrap specific classNames
, bootstrapName
]
......@@ -64,8 +65,8 @@ component = R.hooksComponent componentName cpt where
H.textarea
{ className
, on: { change }
, disabled: elem status [ "disabled" ]
, readOnly: elem status [ "idled" ]
, disabled: elem status [ Disabled ]
, readOnly: elem status [ Idled ]
, placeholder: props.placeholder
, autoComplete: "off"
} []
......@@ -75,11 +76,11 @@ component = R.hooksComponent componentName cpt where
-- | * Also directly returns the newly input value
-- | (usage not so different from `targetValue` of ReactBasic)
onChange :: forall event.
String
ComponentStatus
-> (String -> Effect Unit)
-> event
-> Effect Unit
onChange status callback event = do
if status == "enabled"
if status == Enabled
then callback $ (unsafeCoerce event).target.value
else pure $ unit
else pure unit
......@@ -6,6 +6,7 @@ import Data.Array (elem)
import Data.Foldable (intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Spinner (spinner)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix as R2
import React.SyntheticEvent as SE
......@@ -13,12 +14,12 @@ import Reactix as R
import Reactix.DOM.HTML as H
type Props =
( callback :: Unit -> Effect Unit
( callback :: Unit -> Effect Unit
| Options
)
type Options =
( status :: String
( status :: ComponentStatus
, size :: String
, variant :: String
, type :: String
......@@ -28,7 +29,7 @@ type Options =
options :: Record Options
options =
{ status : "enabled"
{ status : Enabled
, size : "md"
, variant : "primary"
, type : "button"
......@@ -61,7 +62,7 @@ component = R.hooksComponent componentName cpt where
[ props.className
-- BEM classNames
, componentName
, componentName <> "--" <> status
, componentName <> "--" <> show status
-- Bootstrap specific classNames
, bootstrapName
, bootstrapName <> "-" <> props.variant
......@@ -78,11 +79,11 @@ component = R.hooksComponent componentName cpt where
H.button
{ className
, on: { click }
, disabled: elem status [ "disabled", "deferred" ]
, disabled: elem status [ Disabled, Deferred ]
, type: props.type
}
[ R2.if' (status == "deferred") $
[ R2.if' (status == Deferred) $
spinner
{ className: componentName <> "__spinner"
}
......@@ -96,12 +97,12 @@ component = R.hooksComponent componentName cpt where
-- | Clicked event will effectively be triggered according to the
-- | component status props
onClick :: forall event.
String
ComponentStatus
-> (Unit -> Effect Unit)
-> SE.SyntheticEvent_ event
-> Effect Unit
onClick status callback event = do
SE.preventDefault event
if status == "enabled"
if status == Enabled
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
import Data.String as Str
import Data.Symbol (SProxy(..))
import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Aff (Aff, Milliseconds(..), delay, launchAff_)
import Effect.Class (liftEffect)
import Gargantext.Components.App.Data (Boxes)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Components.Category (rating)
import Gargantext.Components.Category.Types (Star(..))
import Gargantext.Components.DocsTable.DocumentFormCreation (documentFormCreation)
......@@ -39,7 +41,7 @@ import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId, get, delete)
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.QueryString (joinQueryStrings, mQueryParam, mQueryParamS, queryParam, queryParamS)
import Gargantext.Utils.Reactix as R2
......@@ -131,13 +133,28 @@ docViewCpt = here.component "docView" cpt where
, params
, query
} _ = do
-- State
cacheState' <- T.useLive T.unequal cacheState
query' <- T.useLive T.unequal query
isDocumentModalVisibleBox <- T.useBox false
onDocumentCreationPending /\ onDocumentCreationPendingBox <-
R2.useBox' false
-- @toggleModalCallback
toggleModal <- pure $ const $
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 $
R.fragment
......@@ -187,7 +204,9 @@ docViewCpt = here.component "docView" cpt where
}
[
documentFormCreation
{}
{ callback: createDocumentCallback
, status: onDocumentCreationPending ? Deferred $ Enabled
}
]
]
......
module Gargantext.Components.DocsTable.DocumentFormCreation
( documentFormCreation
, FormData
) where
import Gargantext.Prelude
import DOM.Simple.Console (log, log3)
import DOM.Simple.Console (log3)
import Data.Either (Either(..))
import Data.Foldable (foldl, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap as B
import Gargantext.Hooks.FormValidation (useFormValidation)
import Gargantext.Hooks.FormValidation.Types (VForm)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Hooks.FormValidation (VForm, useFormValidation)
import Gargantext.Hooks.FormValidation.Unboxed as FV
import Gargantext.Hooks.StateRecord (useStateRecord)
import Gargantext.Utils (nbsp, (?))
......@@ -18,30 +19,27 @@ import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Record (merge)
import Record.Extra (pick)
type DocumentFormData =
( title :: String
, source :: String
, authors :: String
, abstract :: String
type Props =
( callback :: Record FormData -> Effect Unit
, status :: ComponentStatus
| Options
)
documentDefaultData :: Record DocumentFormData
documentDefaultData =
{ title : ""
, source : ""
, authors : ""
, abstract : ""
}
type Options = ( | FormData )
options :: Record Options
options = merge {} defaultData
documentFormCreation :: forall r. R2.OptLeaf Options Props r
documentFormCreation = R2.optLeaf component options
documentFormCreation :: R2.Leaf ()
documentFormCreation = R2.leaf documentFormCreationCpt
documentFormCreationCpt :: R.Component ()
documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
cpt _ _ = do
component :: R.Component Props
component = R.hooksComponent "documentFormCreation" cpt where
cpt props _ = do
-- Hooks
{ state, setStateKey, bindStateKey } <- useStateRecord documentDefaultData
{ state, bindStateKey } <- useStateRecord (pick props :: Record FormData)
fv <- useFormValidation
-- @onSubmit: exec whole form validation and execute callback
......@@ -50,8 +48,8 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
result <- fv.try (\_ -> documentFormValidation state)
case result of
Left err -> log3 "document form error" state err
Right _ -> log "ok"
Left err -> log3 "document form validation error" state err
Right _ -> props.callback state
-- Render
pure $
......@@ -166,7 +164,7 @@ documentFormCreationCpt = R.hooksComponent "documentFormCreation" cpt where
[
B.button
{ callback: \_ -> onSubmit
-- , status: props.status == "deferred" ? "deferred" $ "enabled"
, status: props.status == Deferred ? Deferred $ Enabled
, variant: "primary"
, type: "submit"
, block: true
......@@ -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
where
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