Commit f91c7b77 authored by arturo's avatar arturo

>>> BEGIN dev-phylo-rc1.x

parent 453b3298
Pipeline #2197 failed with stage
......@@ -6,5 +6,6 @@ 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.FormSelect(formSelect) as Exports
import Gargantext.Components.Bootstrap.FormTextarea(formTextarea) as Exports
import Gargantext.Components.Bootstrap.Spinner(spinner) as Exports
......@@ -4,7 +4,7 @@ import Gargantext.Prelude
import Data.Foldable (elem, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), Sizing(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
......@@ -21,7 +21,7 @@ type Options =
, className :: String
, type :: String
, placeholder :: String
, size :: String
, size :: Sizing
)
options :: Record Options
......@@ -30,13 +30,11 @@ options =
, className : ""
, type : "text"
, placeholder : ""
, size : "md"
, size : MediumSize
}
-- | Structural Component for the Bootstrap input
-- |
-- | * size: `"md" (default) | "sm" | "lg"`
-- |
-- | https://getbootstrap.com/docs/4.1/components/forms/
formInput :: forall r. R2.OptLeaf Options Props r
formInput = R2.optLeaf component options
......@@ -61,7 +59,7 @@ component = R.hooksComponent componentName cpt where
, componentName <> "--" <> show status
-- Bootstrap specific classNames
, bootstrapName
, bootstrapName <> "-" <> props.size
, bootstrapName <> "-" <> show props.size
]
change <- pure $ onChange status callback
......@@ -76,6 +74,7 @@ component = R.hooksComponent componentName cpt where
, placeholder: props.placeholder
, type: props.type
, autoComplete: "off"
, value: props.value
}
-- | * Change event will effectively be triggered according to the
......
module Gargantext.Components.Bootstrap.FormSelect (formSelect) where
import Gargantext.Prelude
import Data.Foldable (elem, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), Sizing(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Unsafe.Coerce (unsafeCoerce)
type Props =
( callback :: String -> Effect Unit
, value :: String
| Options
)
type Options =
( status :: ComponentStatus
, className :: String
, type :: String
, placeholder :: String
, size :: Sizing
)
options :: Record Options
options =
{ status : Enabled
, className : ""
, type : "text"
, placeholder : ""
, size : MediumSize
}
-- | Structural Component for the Bootstrap select
-- |
-- | ```purescript
-- | formSelect { callback, value }
-- | [
-- | H.option
-- | { value: "foo" }
-- | [ H.text "foo" ]
-- | ,
-- | H.option
-- | { value: "bar" }
-- | [ H.text "bar" ]
-- | ]
-- | ```
-- |
-- | https://getbootstrap.com/docs/4.1/components/forms/
formSelect :: forall r. R2.OptComponent Options Props r
formSelect = R2.optComponent component options
componentName :: String
componentName = "b-form-select"
bootstrapName :: String
bootstrapName = "form-control"
component :: R.Component Props
component = R.hooksComponent componentName cpt where
cpt props@{ callback
, status
} children = do
-- Computed
className <- pure $ intercalate " "
-- provided custom className
[ props.className
-- BEM classNames
, componentName
, componentName <> "--" <> show status
-- Bootstrap specific classNames
, bootstrapName
, bootstrapName <> "-" <> show props.size
]
change <- pure $ onChange status callback
-- Render
pure $
R2.select
{ className
, on: { change }
, disabled: elem status [ Disabled ]
, readOnly: elem status [ Idled ]
, type: props.type
, value: props.value
}
children
-- | * Change event will effectively be triggered according to the
-- | component status props
-- | * Also directly returns the newly input value
-- | (usage not so different from `targetValue` of ReactBasic)
onChange :: forall event.
ComponentStatus
-> (String -> Effect Unit)
-> event
-> Effect Unit
onChange status callback event = do
if status == Enabled
then callback $ (unsafeCoerce event).target.value
else pure unit
module Gargantext.Components.Bootstrap.Types
( ComponentStatus(..)
, Sizing(..)
) where
import Gargantext.Prelude
......@@ -38,3 +39,28 @@ derive instance Generic ComponentStatus _
derive instance Eq ComponentStatus
instance Show ComponentStatus where
show a = kebabCase $ genericShow a
----------------------------------------------------------------------
-- | Common sizing values used by various Bootstrap components
-- |
-- | Bootstrap components using sizing use:
-- | * only 3 possible values
-- | * `MediumSize` value by default
-- | * (not to be confused with Bootstrap className utilities also using
-- | a measuring scale)
-- |
-- | Examples:
-- | * https://getbootstrap.com/docs/4.1/components/input-group/#sizing
-- | * https://getbootstrap.com/docs/4.1/components/button-group/#sizing
data Sizing =
SmallSize
| MediumSize
| LargeSize
derive instance Generic Sizing _
derive instance Eq Sizing
instance Show Sizing where
show SmallSize = "sm"
show MediumSize = "md"
show LargeSize = "lg"
......@@ -279,9 +279,6 @@ function findValueByPrefix(prefix) {
function drawPhylo(branches, periods, groups, links, aLinks, bLinks, frame) {
/* ** draw the sources box ** */
document.querySelector("#checkSource").style.display = "inline-block";
/* ** draw the search box ** */
......
......@@ -141,6 +141,7 @@ unhide :: Document -> String -> Effect Unit
unhide d s = do
setText s `toElements` "#phyloName"
turnVisible `toElements` "#phyloName"
turnVisible `toElements` "#phyloTopBar"
turnVisible `toElements` ".reset"
turnVisible `toElements` ".label"
turnVisible `toElements` ".heading"
......
......@@ -5,8 +5,10 @@ module Gargantext.Components.PhyloExplorer.Layout
import Gargantext.Prelude
import DOM.Simple (document, window)
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested ((/\))
import Gargantext.Components.PhyloExplorer.Draw (drawPhylo, highlightSource, setGlobalD3Reference, setGlobalDependencies, unhide)
import Gargantext.Components.PhyloExplorer.TopBar (topBar)
import Gargantext.Components.PhyloExplorer.Types (PhyloDataSet(..), Source(..), sortSources)
import Gargantext.Utils (nbsp)
import Gargantext.Utils.Reactix as R2
......@@ -31,6 +33,8 @@ layoutCpt = here.component "layout" cpt where
-- States
sources /\ sourcesBox <- R2.useBox' (mempty :: Array Source)
mTopBarHost <- R.unsafeHooksEffect $ R2.getElementById "portal-topbar"
R.useEffectOnce' $ do
(sortSources >>> flip T.write_ sourcesBox) o.sources
unhide document o.name
......@@ -92,34 +96,9 @@ layoutCpt = here.component "layout" cpt where
-- , className: "button draw"
-- }
-- [ H.text "draw" ]
-- ,
-- <!-- source selector -->
R2.select
{ id: "checkSource"
, className: "select-source"
, defaultValue: ""
, on: { change: \e -> highlightSource window e.target.value }
} $
[
H.option
{ disabled: true
, value: ""
}
[ H.text "select a source ↴" ]
,
H.option
{ value: "unselect" }
[ H.text "unselect source ✕" ]
]
<>
flip map sources
( \(Source { id, label }) ->
H.option
{ value: id }
[ H.text label ]
)
--
,
-- <!-- search bar -->
H.label
{ id: "search-label"
......@@ -243,6 +222,22 @@ layoutCpt = here.component "layout" cpt where
}
[]
,
-- <!-- PORTAL: topbar -->
R2.createPortal' mTopBarHost
[
-- H.div
-- { id: "phyloTopBar"
-- -- , visibility: "hidden"
-- }
-- [
-- topBar
-- { sourceList: sources
-- , sourceCallback: highlightSource window
-- }
-- ]
]
]
--------------------------------------------------------
......
module Gargantext.Components.PhyloExplorer.TopBar
( topBar
) where
import Gargantext.Prelude
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.PhyloExplorer.Types (Source(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
-- @WIP: * change "source" default value "" to `Maybe String`
here :: R2.Here
here = R2.here "Gargantext.Components.PhyloExplorer.TopBar"
type Props =
( sourceCallback :: String -> Effect Unit
, sourceList :: Array Source
)
topBar :: R2.Leaf Props
topBar = R2.leaf topBarCpt
-- topBarCpt :: R.Component Props
-- topBarCpt = here.component "main" cpt where
-- cpt props _ = do
-- -- States
-- let defaultSource = ""
-- source /\ sourceBox <- R2.useBox' defaultSource
-- -- Effects
-- R.useEffect1' source $ props.sourceCallback source
-- -- Render
-- pure $
-- H.div
-- { className: "phylo-topbar" }
-- [
-- B.formSelect
-- { className: "select-source"
-- , value: source
-- , callback: flip T.write_ sourceBox
-- } $
-- [
-- H.option
-- { disabled: true
-- , value: ""
-- }
-- [ H.text "select a source ↴" ]
-- ,
-- H.option
-- { value: "unselect" }
-- [ H.text "unselect source ✕" ]
-- ]
-- <>
-- flip map props.sourceList
-- ( \(Source { id, label }) ->
-- H.option
-- { value: id }
-- [ H.text label ]
-- )
-- ]
topBarCpt :: R.Component Props
topBarCpt = here.component "main" cpt where
cpt props _ = do
-- States
let defaultSource = ""
source /\ sourceBox <- R2.useBox' defaultSource
-- @onChange
onChange <- pure $ \new -> do
T.write_ new sourceBox
props.sourceCallback new
-- Render
pure $
H.div
{ className: "phylo-topbar" }
[
B.formSelect
{ className: "select-source"
, value: source
, callback: onChange
} $
[
H.option
{ disabled: true
, value: ""
}
[ H.text "select a source ↴" ]
,
H.option
{ value: "unselect" }
[ H.text "unselect source ✕" ]
]
<>
flip map props.sourceList
( \(Source { id, label }) ->
H.option
{ value: id }
[ H.text label ]
)
]
......@@ -103,7 +103,9 @@ topBarCpt = here.component "topBar" cpt where
let children = case route' of
GR.PGraphExplorer _s _g -> [ GETB.topBar { boxes } ]
_ -> []
-- @WIP: portal use, remove route pattern matching, send
-- GETB.topBar through below portal
_ -> [ H.div { id: "portal-topbar" } [] ]
pure $ TopBar.topBar { boxes } children
......
......@@ -9,6 +9,7 @@ import DOM.Simple.Document (document)
import DOM.Simple.Element as Element
import DOM.Simple.Event as DE
import DOM.Simple.Types (class IsNode, class IsElement, DOMRect)
import Data.Array (singleton)
import Data.Array as A
import Data.Either (hush)
import Data.Function.Uncurried (Fn1, runFn1, Fn2, runFn2)
......@@ -16,6 +17,7 @@ import Data.Maybe (Maybe(..), fromJust, fromMaybe)
import Data.Nullable (Nullable, null, toMaybe)
import Data.Tuple (Tuple)
import Data.Tuple.Nested ((/\))
import Data.UUID as UUID
import Effect (Effect)
import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Class (liftEffect)
......@@ -495,3 +497,20 @@ useBox' default = do
box <- T.useBox default
b <- useLive' box
pure $ b /\ box
-- | Reactix `fragment` with key support
fragmentWithKey :: String -> Array R.Element -> R.Element
fragmentWithKey key es = R.rawCreateElement (R.react .. "Fragment") { key } es
-- | * Create portal via a `Maybe DOM.Element`,
-- | * Also resolve ReactJS erratic runtime error where portal children element
-- | within it does not have "key" [1]
-- |
-- | [1] `Warning: Each child in a list should have a unique "key" prop.`
createPortal' :: Maybe DOM.Element -> Array R.Element -> R.Element
createPortal' mHost children =
let key = unsafeCoerce UUID.genUUID
in case mHost of
Nothing -> mempty
Just host -> flip R.createPortal host $ singleton $
fragmentWithKey key children
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