Verified Commit 8eb04342 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

Merge branch 'dev' into dev-spago-next

parents 9d146936 2f2711ca
Pipeline #6117 failed with stages
in 8 minutes and 34 seconds
...@@ -52,6 +52,13 @@ $ nix-env --version ...@@ -52,6 +52,13 @@ $ nix-env --version
nix-env (Nix) 2.11.0 nix-env (Nix) 2.11.0
``` ```
Enable de flake experimental feature :
```shell
mkdir ~/.config/nix
echo "experimental-features = nix-command flakes" > ~/.config/nix/nix.conf
```
To build the frontend just execute the install script at the root at the project: To build the frontend just execute the install script at the root at the project:
```shell ```shell
./install ./install
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
"create-react-class": "~15.6.3", "create-react-class": "~15.6.3",
"crypto": "~1.0.1", "crypto": "~1.0.1",
"d3": "~7.6.1", "d3": "~7.6.1",
"debounce": "^2.0.0",
"debouncing": "^22.7.25",
"echarts": "~5.1.2", "echarts": "~5.1.2",
"echarts-for-react": "~3.0.1", "echarts-for-react": "~3.0.1",
"graphology": "~0.25.1", "graphology": "~0.25.1",
...@@ -46,6 +48,7 @@ ...@@ -46,6 +48,7 @@
"secp256k1": "~4.0.2", "secp256k1": "~4.0.2",
"sigma": "~2.4.0", "sigma": "~2.4.0",
"twgl.js": "~5.0.4", "twgl.js": "~5.0.4",
"use-debounce": "^10.0.0",
"uuid": "8.3.2" "uuid": "8.3.2"
}, },
"devDependencies": { "devDependencies": {
...@@ -6335,6 +6338,22 @@ ...@@ -6335,6 +6338,22 @@
"license": "MIT", "license": "MIT",
"optional": true "optional": true
}, },
"node_modules/debounce": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-2.0.0.tgz",
"integrity": "sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA==",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/debouncing": {
"version": "22.7.25",
"resolved": "https://registry.npmjs.org/debouncing/-/debouncing-22.7.25.tgz",
"integrity": "sha512-8X8SS+PEkaBBi1tUVZVT4xFImHI9iQ7uSazoHMjoSJ603hY4ZrffwDg0MExbGnYH+7J3QY2ElnCCJEgaIBZ8bA=="
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"dev": true, "dev": true,
...@@ -13175,6 +13194,17 @@ ...@@ -13175,6 +13194,17 @@
"requires-port": "^1.0.0" "requires-port": "^1.0.0"
} }
}, },
"node_modules/use-debounce": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.0.tgz",
"integrity": "sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A==",
"engines": {
"node": ">= 16.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/util-deprecate": { "node_modules/util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"dev": true, "dev": true,
......
{ {
"name": "Gargantext", "name": "Gargantext",
"version": "0.0.7.1.3", "version": "0.0.7.1.5",
"scripts": { "scripts": {
"build": "spago build", "build": "spago build",
"bundle": "spago bundle --module Main --outfile dist/bundle.js", "bundle": "spago bundle --module Main --outfile dist/bundle.js",
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
"create-react-class": "~15.6.3", "create-react-class": "~15.6.3",
"crypto": "~1.0.1", "crypto": "~1.0.1",
"d3": "~7.6.1", "d3": "~7.6.1",
"debounce": "^2.0.0",
"debouncing": "^22.7.25",
"echarts": "~5.1.2", "echarts": "~5.1.2",
"echarts-for-react": "~3.0.1", "echarts-for-react": "~3.0.1",
"graphology": "~0.25.1", "graphology": "~0.25.1",
...@@ -58,6 +60,7 @@ ...@@ -58,6 +60,7 @@
"secp256k1": "~4.0.2", "secp256k1": "~4.0.2",
"sigma": "~2.4.0", "sigma": "~2.4.0",
"twgl.js": "~5.0.4", "twgl.js": "~5.0.4",
"use-debounce": "^10.0.0",
"uuid": "8.3.2" "uuid": "8.3.2"
}, },
"devDependencies": { "devDependencies": {
......
...@@ -3,7 +3,7 @@ workspace: ...@@ -3,7 +3,7 @@ workspace:
gargantext: gargantext:
path: ./ path: ./
dependencies: dependencies:
- aff - aff: ">=7.1.0 <8.0.0"
- aff-promise: ">=4.0.0 <5.0.0" - aff-promise: ">=4.0.0 <5.0.0"
- affjax: ">=13.0.0 <14.0.0" - affjax: ">=13.0.0 <14.0.0"
- affjax-web: ">=1.0.0 <2.0.0" - affjax-web: ">=1.0.0 <2.0.0"
...@@ -21,6 +21,8 @@ workspace: ...@@ -21,6 +21,8 @@ workspace:
- d3: "*" - d3: "*"
- data-default: "*" - data-default: "*"
- datetime: ">=6.1.0 <7.0.0" - datetime: ">=6.1.0 <7.0.0"
- debouncing: ">=0.1.0 <0.2.0"
- debug: ">=6.0.2 <7.0.0"
- dom-filereader: ">=7.0.0 <8.0.0" - dom-filereader: ">=7.0.0 <8.0.0"
- dom-simple: ">=0.4.0 <0.5.0" - dom-simple: ">=0.4.0 <0.5.0"
- effect: ">=4.0.0 <5.0.0" - effect: ">=4.0.0 <5.0.0"
...@@ -57,7 +59,7 @@ workspace: ...@@ -57,7 +59,7 @@ workspace:
- profunctor-lenses: ">=8.0.0 <9.0.0" - profunctor-lenses: ">=8.0.0 <9.0.0"
- random: ">=6.0.0 <7.0.0" - random: ">=6.0.0 <7.0.0"
- react: ">=11.0.0 <12.0.0" - react: ">=11.0.0 <12.0.0"
- reactix: ">=0.6.0 <0.7.0" - reactix: ">=0.6.1 <0.7.0"
- record: ">=4.0.0 <5.0.0" - record: ">=4.0.0 <5.0.0"
- record-extra: ">=5.0.1 <6.0.0" - record-extra: ">=5.0.1 <6.0.0"
- routing: ">=11.0.0 <12.0.0" - routing: ">=11.0.0 <12.0.0"
...@@ -117,6 +119,8 @@ workspace: ...@@ -117,6 +119,8 @@ workspace:
- d3 - d3
- data-default - data-default
- datetime - datetime
- debouncing
- debug
- distributive - distributive
- dom-filereader - dom-filereader
- dom-simple - dom-simple
...@@ -232,7 +236,7 @@ workspace: ...@@ -232,7 +236,7 @@ workspace:
- web-xhr - web-xhr
package_set: package_set:
address: address:
registry: 50.11.0 registry: 50.13.1
compiler: ">=0.15.15 <0.16.0" compiler: ">=0.15.15 <0.16.0"
content: content:
abc-parser: 2.0.1 abc-parser: 2.0.1
...@@ -247,6 +251,7 @@ workspace: ...@@ -247,6 +251,7 @@ workspace:
affjax-node: 1.0.0 affjax-node: 1.0.0
affjax-web: 1.0.0 affjax-web: 1.0.0
ansi: 7.0.0 ansi: 7.0.0
apexcharts: 0.5.0
applicative-phases: 1.0.0 applicative-phases: 1.0.0
argonaut: 9.0.0 argonaut: 9.0.0
argonaut-aeson-generic: 0.4.1 argonaut-aeson-generic: 0.4.1
...@@ -308,6 +313,7 @@ workspace: ...@@ -308,6 +313,7 @@ workspace:
coroutines: 7.0.0 coroutines: 7.0.0
css: 6.0.0 css: 6.0.0
css-frameworks: 1.0.1 css-frameworks: 1.0.1
csv-stream: 1.1.7
data-mvc: 0.0.2 data-mvc: 0.0.2
datetime: 6.1.0 datetime: 6.1.0
datetime-parsing: 0.2.0 datetime-parsing: 0.2.0
...@@ -545,7 +551,7 @@ workspace: ...@@ -545,7 +551,7 @@ workspace:
pointed-list: 0.5.1 pointed-list: 0.5.1
polymorphic-vectors: 4.0.0 polymorphic-vectors: 4.0.0
posix-types: 6.0.0 posix-types: 6.0.0
postgresql: 1.3.0 postgresql: 1.5.1
precise: 6.0.0 precise: 6.0.0
precise-datetime: 7.0.0 precise-datetime: 7.0.0
prelude: 6.0.1 prelude: 6.0.1
...@@ -726,12 +732,14 @@ workspace: ...@@ -726,12 +732,14 @@ workspace:
data-default: data-default:
git: https://github.com/garganscript/purescript-data-default.git git: https://github.com/garganscript/purescript-data-default.git
ref: v0.4.0 ref: v0.4.0
debouncing: 0.1.2
graphql-client: graphql-client:
git: https://github.com/garganscript/purescript-graphql-client.git git: https://github.com/garganscript/purescript-graphql-client.git
ref: spago-next-9.3.2 ref: spago-next-9.3.2
markdown-it: markdown-it:
git: https://github.com/garganscript/purescript-markdown-it.git git: https://github.com/garganscript/purescript-markdown-it.git
ref: spago-next ref: spago-next
reactix: 0.6.1
sequences: sequences:
git: https://github.com/garganscript/purescript-sequences.git git: https://github.com/garganscript/purescript-sequences.git
ref: v3.0.2-spago-next ref: v3.0.2-spago-next
...@@ -1048,6 +1056,20 @@ packages: ...@@ -1048,6 +1056,20 @@ packages:
- partial - partial
- prelude - prelude
- tuples - tuples
debouncing:
type: registry
version: 0.1.2
integrity: sha256-2Ajskjmc+r3gnpcv6L8U4BfiSKj4N7sCINiBD99RjO8=
dependencies:
- effect
- prelude
debug:
type: registry
version: 6.0.2
integrity: sha256-vmkYFuXYuELBzeauvgHG6E6Kf/Hp1dAnxwE9ByHfwSg=
dependencies:
- functions
- prelude
distributive: distributive:
type: registry type: registry
version: 6.0.0 version: 6.0.0
...@@ -1822,8 +1844,8 @@ packages: ...@@ -1822,8 +1844,8 @@ packages:
- unsafe-coerce - unsafe-coerce
reactix: reactix:
type: registry type: registry
version: 0.6.0 version: 0.6.1
integrity: sha256-gaF3igbCsTmaGxfbykWaBcyv4n7AHVmQRstZ/msNfJw= integrity: sha256-mM6JZFWfeMhgMJa9oGdzNchkp/Xcnv2e/oGc0nZp6EQ=
dependencies: dependencies:
- dom-simple - dom-simple
- effect - effect
......
workspace: workspace:
packageSet: packageSet:
registry: 50.11.0 registry: 50.13.1
extraPackages: extraPackages:
# garganscript packages # garganscript packages
d3: d3:
git: https://github.com/garganscript/purescript-d3.git git: https://github.com/garganscript/purescript-d3.git
ref: v0.11.0 ref: v0.11.0
debouncing: 0.1.2
reactix: 0.6.1
string-search: string-search:
git: https://gitlab.iscpif.fr/gargantext/purescript-string-search.git git: https://gitlab.iscpif.fr/gargantext/purescript-string-search.git
ref: spago-next ref: spago-next
...@@ -37,10 +39,7 @@ package: ...@@ -37,10 +39,7 @@ package:
name: gargantext name: gargantext
dependencies: dependencies:
# debugging # debugging
# - debug: ">=6.0.2 <7.0.0" - aff: ">=7.1.0 <8.0.0"
# - psci-support: ">=6.0.0 <7.0.0"
- aff
- aff-promise: ">=4.0.0 <5.0.0" - aff-promise: ">=4.0.0 <5.0.0"
- affjax: ">=13.0.0 <14.0.0" - affjax: ">=13.0.0 <14.0.0"
- affjax-web: ">=1.0.0 <2.0.0" - affjax-web: ">=1.0.0 <2.0.0"
...@@ -58,6 +57,8 @@ package: ...@@ -58,6 +57,8 @@ package:
- d3: "*" - d3: "*"
- data-default: "*" - data-default: "*"
- datetime: ">=6.1.0 <7.0.0" - datetime: ">=6.1.0 <7.0.0"
- debouncing: ">=0.1.0 <0.2.0"
- debug: ">=6.0.2 <7.0.0"
- dom-filereader: ">=7.0.0 <8.0.0" - dom-filereader: ">=7.0.0 <8.0.0"
- dom-simple: ">=0.4.0 <0.5.0" - dom-simple: ">=0.4.0 <0.5.0"
- effect: ">=4.0.0 <5.0.0" - effect: ">=4.0.0 <5.0.0"
...@@ -94,7 +95,7 @@ package: ...@@ -94,7 +95,7 @@ package:
- profunctor-lenses: ">=8.0.0 <9.0.0" - profunctor-lenses: ">=8.0.0 <9.0.0"
- random: ">=6.0.0 <7.0.0" - random: ">=6.0.0 <7.0.0"
- react: ">=11.0.0 <12.0.0" - react: ">=11.0.0 <12.0.0"
- reactix: ">=0.6.0 <0.7.0" - reactix: ">=0.6.1 <0.7.0"
- record: ">=4.0.0 <5.0.0" - record: ">=4.0.0 <5.0.0"
- record-extra: ">=5.0.1 <6.0.0" - record-extra: ">=5.0.1 <6.0.0"
- routing: ">=11.0.0 <12.0.0" - routing: ">=11.0.0 <12.0.0"
...@@ -140,7 +141,6 @@ package: ...@@ -140,7 +141,6 @@ package:
- UnusedName - UnusedName
- UnusedTypeVar - UnusedTypeVar
test: test:
main: Test.Main main: Test.Main
dependencies: dependencies:
......
...@@ -34,6 +34,7 @@ actionDownloadCpt = here.component "actionDownload" cpt where ...@@ -34,6 +34,7 @@ actionDownloadCpt = here.component "actionDownload" cpt where
cpt props@{ nodeType: GT.Graph } _ = pure $ actionDownloadGraph props [] cpt props@{ nodeType: GT.Graph } _ = pure $ actionDownloadGraph props []
cpt props@{ nodeType: GT.NodeList } _ = pure $ actionDownloadNodeList props [] cpt props@{ nodeType: GT.NodeList } _ = pure $ actionDownloadNodeList props []
cpt props@{ nodeType: GT.NodeTexts } _ = pure $ actionDownloadNodeTexts props [] cpt props@{ nodeType: GT.NodeTexts } _ = pure $ actionDownloadNodeTexts props []
cpt props@{ nodeType: GT.Phylo } _ = pure $ actionDownloadPhylo props []
cpt props@{ nodeType: _ } _ = pure $ actionDownloadOther props [] cpt props@{ nodeType: _ } _ = pure $ actionDownloadOther props []
actionDownloadCorpus :: R2.Component ActionDownload actionDownloadCorpus :: R2.Component ActionDownload
...@@ -156,6 +157,51 @@ actionDownloadNodeTextsCpt = here.component "actionDownloadNodeTexts" cpt where ...@@ -156,6 +157,51 @@ actionDownloadNodeTextsCpt = here.component "actionDownloadNodeTexts" cpt where
info :: NodeTextsDownloadFormat -> String info :: NodeTextsDownloadFormat -> String
info t = "Info about the Documents as " <> show t <> " format" info t = "Info about the Documents as " <> show t <> " format"
data PhyloDownloadFormat = PH_JSON | PH_DOT
derive instance Eq PhyloDownloadFormat
derive instance Generic PhyloDownloadFormat _
instance Show PhyloDownloadFormat where
show PH_JSON = "JSON"
show PH_DOT = "DOT"
urlPhyloDownloadFormat :: PhyloDownloadFormat -> String
urlPhyloDownloadFormat PH_JSON = "json"
urlPhyloDownloadFormat PH_DOT = "dot"
readPhyloDownloadFormat :: String -> PhyloDownloadFormat
readPhyloDownloadFormat "JSON" = PH_JSON
readPhyloDownloadFormat "DOT" = PH_DOT
readPhyloDownloadFormat _ = PH_DOT
actionDownloadPhylo :: R2.Component ActionDownload
actionDownloadPhylo = R.createElement actionDownloadPhyloCpt
actionDownloadPhyloCpt :: R.Component ActionDownload
actionDownloadPhyloCpt = here.component "actionDownloadPhylo" cpt where
cpt { id, session } _ = do
downloadFormat <- T.useBox PH_DOT
downloadFormat' <- T.useLive T.unequal downloadFormat
pure $ Tools.panelWithSubmitButtonHref { action: DownloadNode
, href: href downloadFormat'
, mError: Nothing }
[ R2.select { className: "form-control"
, defaultValue: show downloadFormat'
, on: { change: onChange downloadFormat } }
[ opt PH_JSON
, opt PH_DOT
]
, H.div {} [ H.text $ info downloadFormat' ]
]
where
opt t = H.option { value: show t } [ H.text $ show t ]
onChange downloadFormat e = T.write_ (readPhyloDownloadFormat $ R.unsafeEventValue e) downloadFormat
href :: PhyloDownloadFormat -> String
href t = url session $ Routes.NodeAPI GT.Phylo (Just id) ("export/" <> urlPhyloDownloadFormat t)
info :: PhyloDownloadFormat -> String
info t = "Info about the Phylo as " <> show t <> " format"
{- {-
-- TODO fix the route -- TODO fix the route
actionDownload GT.Texts id session = pure $ panel [H.div {} [H.text info]] actionDownload GT.Texts id session = pure $ panel [H.div {} [H.text info]]
......
...@@ -288,6 +288,7 @@ settingsBoxLens Notes = ...@@ -288,6 +288,7 @@ settingsBoxLens Notes =
] ]
settingsBoxLens Phylo = settingsBoxLens Phylo =
_buttons .~ [ Reconstruct _buttons .~ [ Reconstruct
, Download
, ShareURL , ShareURL
, Delete , Delete
] ]
......
...@@ -235,6 +235,8 @@ graphViewCpt = R.memo' $ here.component "graphView" cpt where ...@@ -235,6 +235,8 @@ graphViewCpt = R.memo' $ here.component "graphView" cpt where
, sigmaRef , sigmaRef
} _ = do } _ = do
-- { edgeConfluence, edgeWeight } <- GraphStore.use
-- edgeConfluence' <- R2.useLive' edgeConfluence -- edgeConfluence' <- R2.useLive' edgeConfluence
-- edgeWeight' <- R2.useLive' edgeWeight -- edgeWeight' <- R2.useLive' edgeWeight
-- nodeSize' <- R2.useLive' nodeSize -- nodeSize' <- R2.useLive' nodeSize
...@@ -410,7 +412,11 @@ hooksTransformGraph = do ...@@ -410,7 +412,11 @@ hooksTransformGraph = do
params <- transformGraphStoreParams params <- transformGraphStoreParams
graph' <- R2.useLive' store.graph graph' <- R2.useLive' store.graph
-- R.useEffect' $ do
-- here.log2 "[hooksTransformGraph] hashed" $ hashLiveProps params
R.useEffect2' (hashLiveProps params) graph' $ do R.useEffect2' (hashLiveProps params) graph' $ do
-- here.log2 "[hooksTransformGraph] transformed" $ transformGraph graph' params
T.write_ (transformGraph graph' params) store.transformedGraph T.write_ (transformGraph graph' params) store.transformedGraph
transformGraph :: SigmaxT.SGraph -> Record LiveProps -> SigmaxT.SGraph transformGraph :: SigmaxT.SGraph -> Record LiveProps -> SigmaxT.SGraph
...@@ -450,8 +456,8 @@ transformGraph graph { edgeConfluence' ...@@ -450,8 +456,8 @@ transformGraph graph { edgeConfluence'
edge { hidden = true } edge { hidden = true }
edgeHideWeight :: Record SigmaxT.Edge -> Record SigmaxT.Edge edgeHideWeight :: Record SigmaxT.Edge -> Record SigmaxT.Edge
edgeHideWeight edge@{ weightIdx } = edgeHideWeight edge@{ weight } =
if Range.within edgeWeight' $ toNumber weightIdx then if Range.within edgeWeight' weight then
edge edge
else else
edge { hidden = true } edge { hidden = true }
......
...@@ -44,6 +44,7 @@ type Store = ...@@ -44,6 +44,7 @@ type Store =
, edgeConfluence :: T.Box Range.NumberRange , edgeConfluence :: T.Box Range.NumberRange
, edgeConfluenceRange :: T.Box Range.NumberRange , edgeConfluenceRange :: T.Box Range.NumberRange
, edgeWeight :: T.Box Range.NumberRange , edgeWeight :: T.Box Range.NumberRange
, edgeWeightRange :: T.Box Range.NumberRange
, forceAtlasState :: T.Box SigmaxT.ForceAtlasState , forceAtlasState :: T.Box SigmaxT.ForceAtlasState
, noverlapState :: T.Box SigmaxT.NoverlapState , noverlapState :: T.Box SigmaxT.NoverlapState
, graphStage :: T.Box GET.Stage , graphStage :: T.Box GET.Stage
...@@ -79,6 +80,7 @@ type State = ...@@ -79,6 +80,7 @@ type State =
, edgeConfluence :: Range.NumberRange , edgeConfluence :: Range.NumberRange
, edgeConfluenceRange :: Range.NumberRange , edgeConfluenceRange :: Range.NumberRange
, edgeWeight :: Range.NumberRange , edgeWeight :: Range.NumberRange
, edgeWeightRange :: Range.NumberRange
, forceAtlasState :: SigmaxT.ForceAtlasState , forceAtlasState :: SigmaxT.ForceAtlasState
, noverlapState :: SigmaxT.NoverlapState , noverlapState :: SigmaxT.NoverlapState
, graphStage :: GET.Stage , graphStage :: GET.Stage
...@@ -109,6 +111,7 @@ options :: ...@@ -109,6 +111,7 @@ options ::
, mouseSelectorSize :: Number , mouseSelectorSize :: Number
, multiSelectEnabled :: Boolean , multiSelectEnabled :: Boolean
, edgeConfluence :: Range.NumberRange , edgeConfluence :: Range.NumberRange
, edgeWeight :: Range.NumberRange
, graphStage :: GET.Stage , graphStage :: GET.Stage
, nodeSize :: Range.NumberRange , nodeSize :: Range.NumberRange
--, showLouvain :: Boolean --, showLouvain :: Boolean
...@@ -131,6 +134,7 @@ options = ...@@ -131,6 +134,7 @@ options =
, labelRenderedSizeThreshold : 2.0 , labelRenderedSizeThreshold : 2.0
, mouseSelectorSize : 15.0 , mouseSelectorSize : 15.0
, edgeConfluence : Range.Closed { min: 0.0, max: 1.0 } , edgeConfluence : Range.Closed { min: 0.0, max: 1.0 }
, edgeWeight : Range.Closed { min: 0.0, max: 1.0 }
, graphStage : GET.Init , graphStage : GET.Init
, nodeSize : Range.Closed { min: 0.0, max: 100.0 } , nodeSize : Range.Closed { min: 0.0, max: 100.0 }
--, showLouvain : false --, showLouvain : false
......
...@@ -11,7 +11,7 @@ import Effect.Timer (setTimeout) ...@@ -11,7 +11,7 @@ import Effect.Timer (setTimeout)
import Gargantext.Components.Bootstrap as B import Gargantext.Components.Bootstrap as B
import Gargantext.Components.GraphExplorer.Store as GraphStore import Gargantext.Components.GraphExplorer.Store as GraphStore
import Gargantext.Components.GraphExplorer.Toolbar.Buttons (cameraButton, centerButton, edgesToggleButton, louvainButton, pauseForceAtlasButton, pauseNoverlapButton, multiSelectEnabledButton) import Gargantext.Components.GraphExplorer.Toolbar.Buttons (cameraButton, centerButton, edgesToggleButton, louvainButton, pauseForceAtlasButton, pauseNoverlapButton, multiSelectEnabledButton)
import Gargantext.Components.GraphExplorer.Toolbar.RangeControl (edgeConfluenceControl, nodeSizeControl) import Gargantext.Components.GraphExplorer.Toolbar.RangeControl (edgeConfluenceControl, edgeWeightControl, nodeSizeControl)
import Gargantext.Components.GraphExplorer.Toolbar.SlideButton (labelSizeButton, labelRenderedSizeThresholdButton, mouseSelectorSizeSlider) import Gargantext.Components.GraphExplorer.Toolbar.SlideButton (labelSizeButton, labelRenderedSizeThresholdButton, mouseSelectorSizeSlider)
import Gargantext.Components.GraphExplorer.Types as GET import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Hooks.Sigmax.ForceAtlas2 as ForceAtlas import Gargantext.Hooks.Sigmax.ForceAtlas2 as ForceAtlas
...@@ -52,7 +52,8 @@ controlsCpt = R.memo' $ here.component "controls" cpt where ...@@ -52,7 +52,8 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
-- | -- |
{ edgeConfluence { edgeConfluence
, edgeConfluenceRange , edgeConfluenceRange
-- , edgeWeight , edgeWeight
, edgeWeightRange
, forceAtlasState , forceAtlasState
, noverlapState , noverlapState
, graph , graph
...@@ -80,6 +81,7 @@ controlsCpt = R.memo' $ here.component "controls" cpt where ...@@ -80,6 +81,7 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
selectedNodeIds' <- R2.useLive' selectedNodeIds selectedNodeIds' <- R2.useLive' selectedNodeIds
showSidebar' <- R2.useLive' showSidebar showSidebar' <- R2.useLive' showSidebar
edgeConfluenceRange' <- R2.useLive' edgeConfluenceRange edgeConfluenceRange' <- R2.useLive' edgeConfluenceRange
edgeWeightRange' <- R2.useLive' edgeWeightRange
nodeSizeRange' <- R2.useLive' nodeSizeRange nodeSizeRange' <- R2.useLive' nodeSizeRange
-- session <- useSession -- session <- useSession
...@@ -207,12 +209,10 @@ controlsCpt = R.memo' $ here.component "controls" cpt where ...@@ -207,12 +209,10 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
} }
, ,
gap, gap gap, gap
, , edgeWeightControl
labelRenderedSizeThresholdButton { forceAtlasState
{ forceAtlasState , range: edgeWeightRange'
, sigmaRef , state: edgeWeight }
, state: labelRenderedSizeThreshold
}
] ]
, ,
-- Run spatialization -- Run spatialization
...@@ -321,12 +321,12 @@ controlsCpt = R.memo' $ here.component "controls" cpt where ...@@ -321,12 +321,12 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
{ forceAtlasState { forceAtlasState
, range: edgeConfluenceRange' , range: edgeConfluenceRange'
, state: edgeConfluence } , state: edgeConfluence }
{- , , gap
edgeWeightControl , labelRenderedSizeThresholdButton
{ forceAtlasState { forceAtlasState
, range: edgeWeightRange , sigmaRef
, state: edgeWeight } , state: labelRenderedSizeThreshold
-} }
, ,
gap, gap gap, gap
, ,
......
...@@ -6,19 +6,29 @@ module Gargantext.Components.GraphExplorer.Toolbar.RangeControl ...@@ -6,19 +6,29 @@ module Gargantext.Components.GraphExplorer.Toolbar.RangeControl
, nodeSizeControl , nodeSizeControl
) where ) where
import Data.Maybe (Maybe(..))
import Data.Tuple.Nested((/\))
import Debug (spy)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Effect.Debouncing as Debounce
import FFI.Simple (delay)
import Gargantext.Components.RangeSlider as RS
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2
import Prelude import Prelude
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
import Gargantext.Components.RangeSlider as RS
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
import Gargantext.Utils.Range as Range
import Gargantext.Utils.Reactix as R2
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.RangeControl" here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.RangeControl"
defaultThrottleInterval :: Int
defaultThrottleInterval = 500
type Props = type Props =
( caption :: String ( caption :: String
, sliderProps :: Record RS.Props , sliderProps :: Record RS.Props
...@@ -54,22 +64,24 @@ edgeConfluenceControlCpt :: R.Component EdgeConfluenceControlProps ...@@ -54,22 +64,24 @@ edgeConfluenceControlCpt :: R.Component EdgeConfluenceControlProps
edgeConfluenceControlCpt = here.component "edgeConfluenceControl" cpt edgeConfluenceControlCpt = here.component "edgeConfluenceControl" cpt
where where
cpt { forceAtlasState cpt { forceAtlasState
, range: Range.Closed { min, max } , range
, state , state
} _ = do } _ = do
forceAtlasState' <- R2.useLive' forceAtlasState forceAtlasState' <- R2.useLive' forceAtlasState
state' <- T.useLive T.unequal state state' <- T.useLive T.unequal state
pure $ rangeControl { pure $ rangeControl {
caption: "Edge Confluence Weight" caption: "Edge Confluence Weight"
, sliderProps: { , sliderProps: {
bounds: Range.Closed { min, max } bounds: range
, epsilon: 0.01 , epsilon: 0.01
, height: 5.0 , height: 5.0
, initialValue: state' , initialValue: state'
, onChange: \rng -> T.write_ rng state , onChange: \rng -> T.write_ rng state
, status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState' , status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
, step: 1.0 , step: 1.0
, throttleInterval: Just defaultThrottleInterval
, width: 10.0 , width: 10.0
} }
} }
...@@ -88,22 +100,27 @@ edgeWeightControlCpt :: R.Component EdgeWeightControlProps ...@@ -88,22 +100,27 @@ edgeWeightControlCpt :: R.Component EdgeWeightControlProps
edgeWeightControlCpt = here.component "edgeWeightControl" cpt edgeWeightControlCpt = here.component "edgeWeightControl" cpt
where where
cpt { forceAtlasState cpt { forceAtlasState
, range: Range.Closed { min, max } , range: range@(Range.Closed { min, max })
, state , state
} _ = do } _ = do
forceAtlasState' <- R2.useLive' forceAtlasState forceAtlasState' <- R2.useLive' forceAtlasState
state' <- T.useLive T.unequal state state' <- T.useLive T.unequal state
pure $ rangeControl { pure $ rangeControl {
caption: "Edge Weight" caption: "Edge Weight"
, sliderProps: { , sliderProps: {
bounds: Range.Closed { min, max } bounds: range
, initialValue: state' , initialValue: state'
, epsilon: 1.0 , epsilon: (max - min) / 100.0
, height: 5.0 , height: 5.0
, onChange: \rng -> T.write_ rng state , onChange: \rng -> T.write_ rng state
-- , onChange: \rng -> Debounce.call onChange rng
-- , onChange: \rng -> RD.callDebouncedCallback rd rng
-- , onChange: onChange'
, status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState' , status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
, step: 1.0 , step: 1.0
, throttleInterval: Just defaultThrottleInterval
, width: 10.0 , width: 10.0
} }
} }
...@@ -138,6 +155,7 @@ nodeSizeControlCpt = here.component "nodeSizeControl" cpt ...@@ -138,6 +155,7 @@ nodeSizeControlCpt = here.component "nodeSizeControl" cpt
, onChange: \rng -> T.write_ rng state , onChange: \rng -> T.write_ rng state
, status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState' , status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
, step: 1.0 , step: 1.0
, throttleInterval: Just defaultThrottleInterval
, width: 10.0 , width: 10.0
} }
} }
...@@ -7,10 +7,11 @@ module Gargantext.Components.GraphExplorer.Toolbar.SlideButton ...@@ -7,10 +7,11 @@ module Gargantext.Components.GraphExplorer.Toolbar.SlideButton
) where ) where
import Data.Map as Map import Data.Map as Map
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..), fromMaybe)
import Data.Number as DN import Data.Number as DN
import Prelude
import Effect (Effect) import Effect (Effect)
import Effect.Debouncing as Debounce
import Prelude
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
...@@ -25,20 +26,29 @@ import Gargantext.Utils.Reactix as R2 ...@@ -25,20 +26,29 @@ import Gargantext.Utils.Reactix as R2
here :: R2.Here here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.SlideButton" here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.SlideButton"
defaultThrottleInterval :: Int
defaultThrottleInterval = 500
type Props = type Props =
( caption :: String ( caption :: String
, forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState , forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
, min :: Number , min :: Number
, max :: Number , max :: Number
, onChange :: forall e. e -> Effect Unit , onChange :: Number -> Effect Unit
, state :: T.Box Number , state :: T.Box Number
, throttleInterval :: Maybe Int -- then Nothing, no throttling is done
) )
sizeButton :: Record Props -> R.Element sizeButton :: Record Props -> R.Element
sizeButton props = R.createElement sizeButtonCpt props [] sizeButton props = R.createElement sizeButtonCpt props []
sizeButtonCpt :: R.Component Props sizeButtonCpt :: R.Component Props
sizeButtonCpt = here.component "sizeButton" cpt where sizeButtonCpt = here.component "sizeButton" cpt where
cpt { state, caption, forceAtlasState, min, max, onChange } _ = do cpt { state, caption, forceAtlasState, min, max, onChange, throttleInterval } _ = do
let throttled = Debounce.throttleWithDebounceAtEnd onChange (fromMaybe 0 throttleInterval)
let onChangeThrottled = case throttleInterval of
Nothing -> onChange
Just ti -> \rng -> Debounce.call throttled rng
defaultValue <- T.useLive T.unequal state defaultValue <- T.useLive T.unequal state
forceAtlasState' <- R2.useLive' forceAtlasState forceAtlasState' <- R2.useLive' forceAtlasState
...@@ -61,7 +71,11 @@ sizeButtonCpt = here.component "sizeButton" cpt where ...@@ -61,7 +71,11 @@ sizeButtonCpt = here.component "sizeButton" cpt where
, min: show min , min: show min
, max: show max , max: show max
, defaultValue , defaultValue
, on: { input: onChange } , on: { input: \e -> do
let v = DN.fromString $ R.unsafeEventValue e
case v of
Nothing -> pure unit
Just vv -> onChangeThrottled vv }
, className: "range-simple__input" , className: "range-simple__input"
, disabled: status == Disabled , disabled: status == Disabled
} }
...@@ -92,30 +106,27 @@ labelSizeButtonCpt = here.component "labelSizeButton" cpt ...@@ -92,30 +106,27 @@ labelSizeButtonCpt = here.component "labelSizeButton" cpt
, forceAtlasState , forceAtlasState
, min: minLabelSize , min: minLabelSize
, max: maxLabelSize , max: maxLabelSize
, onChange: \e -> do , onChange: \newValue -> do
let sigma = R.readRef sigmaRef let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
case newValue' of let ratio = (newValue - minLabelSize) / (defaultLabelSize - minLabelSize)
Nothing -> pure unit let nodes = SigmaxTypes.graphNodes graph'
Just newValue -> let nodesResized = (\n@{ size } -> n { size = size * ratio }) <$> nodes
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do let nodesMap = SigmaxTypes.idMap nodesResized
let ratio = (newValue - minLabelSize) / (defaultLabelSize - minLabelSize) Graphology.forEachNode (Sigma.graph s) $ \{ id } -> do
let nodes = SigmaxTypes.graphNodes graph' case Map.lookup id nodesMap of
let nodesResized = (\n@{ size } -> n { size = size * ratio }) <$> nodes Nothing -> pure unit
let nodesMap = SigmaxTypes.idMap nodesResized Just { size } -> Graphology.mergeNodeAttributes (Sigma.graph s) id { size }
Graphology.forEachNode (Sigma.graph s) $ \{ id } -> do
case Map.lookup id nodesMap of Sigma.setSettings s {
Nothing -> pure unit defaultLabelSize: newValue
Just { size } -> Graphology.mergeNodeAttributes (Sigma.graph s) id { size } , drawLabels: true
, labelSize: newValue
Sigma.setSettings s { -- , maxNodeSize: newValue / 2.5
defaultLabelSize: newValue --, labelSizeRatio: newValue / 2.5
, drawLabels: true }
, labelSize: newValue T.write_ newValue state
-- , maxNodeSize: newValue / 2.5 , throttleInterval: Just defaultThrottleInterval
--, labelSizeRatio: newValue / 2.5
}
T.write_ newValue state
} }
type LabelRenderedSizeThresholdButtonProps = type LabelRenderedSizeThresholdButtonProps =
...@@ -135,17 +146,14 @@ labelRenderedSizeThresholdButtonCpt = here.component "labelRenderedSizeThreshold ...@@ -135,17 +146,14 @@ labelRenderedSizeThresholdButtonCpt = here.component "labelRenderedSizeThreshold
, forceAtlasState , forceAtlasState
, min: 0.0 , min: 0.0
, max: 10.0 , max: 10.0
, onChange: \e -> do , onChange: \newValue -> do
let sigma = R.readRef sigmaRef let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e Sigmax.dependOnSigma sigma "[labelRenderdSizeThresholdButton] sigma: Nothing" $ \s -> do
case newValue' of Sigma.setSettings s {
Nothing -> pure unit labelRenderedSizeThreshold: newValue
Just newValue -> }
Sigmax.dependOnSigma sigma "[labelRenderdSizeThresholdButton] sigma: Nothing" $ \s -> do T.write_ newValue state
Sigma.setSettings s { , throttleInterval: Just defaultThrottleInterval
labelRenderedSizeThreshold: newValue
}
T.write_ newValue state
} }
type MouseSelectorSizeSliderProps = type MouseSelectorSizeSliderProps =
...@@ -164,16 +172,13 @@ mouseSelectorSizeSliderCpt = here.component "mouseSelectorSizeSlider" cpt ...@@ -164,16 +172,13 @@ mouseSelectorSizeSliderCpt = here.component "mouseSelectorSizeSlider" cpt
, forceAtlasState , forceAtlasState
, min: 1.0 , min: 1.0
, max: 100.0 , max: 100.0
, onChange: \e -> do , onChange: \newValue -> do
let sigma = R.readRef sigmaRef let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e Sigmax.dependOnSigma sigma "[mouseSelectorSizeButton] sigma: Nothing" $ \s -> do
case newValue' of Sigma.setSettings s {
Nothing -> pure unit mouseSelectorSize: newValue
Just newValue -> }
Sigmax.dependOnSigma sigma "[mouseSelectorSizeButton] sigma: Nothing" $ \s -> do T.write_ newValue state
Sigma.setSettings s {
mouseSelectorSize: newValue
}
T.write_ newValue state
, state , state
, throttleInterval: Just defaultThrottleInterval
} }
...@@ -120,7 +120,7 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt ...@@ -120,7 +120,7 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
onInput :: forall event. T.Box Completions -> event -> Effect Unit onInput :: forall event. T.Box Completions -> event -> Effect Unit
onInput completions e = do onInput completions e = do
let val = S.trim $ R.unsafeEventValue e let val = R.unsafeEventValue e
T.write_ val state T.write_ val state
cs <- autocompleteSearch val cs <- autocompleteSearch val
T.write_ cs completions T.write_ cs completions
......
...@@ -5,7 +5,6 @@ module Gargantext.Components.Nodes.Graph ...@@ -5,7 +5,6 @@ module Gargantext.Components.Nodes.Graph
import Gargantext.Prelude import Gargantext.Prelude
import Data.Array as A import Data.Array as A
import Data.Int as I
import Data.Maybe (Maybe(..), isJust, maybe) import Data.Maybe (Maybe(..), isJust, maybe)
import Data.Sequence as Seq import Data.Sequence as Seq
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
...@@ -165,6 +164,11 @@ hydrateStoreCpt = here.component "hydrateStore" cpt where ...@@ -165,6 +164,11 @@ hydrateStoreCpt = here.component "hydrateStore" cpt where
-- | Precompute some values -- | Precompute some values
-- | -- |
let edgesWeightSorted = A.sortWith (_.weight) $ Seq.toUnfoldable $ SigmaxT.graphEdges graph
let edgeWeightMin = maybe 0.0 _.weight $ A.head edgesWeightSorted
let edgeWeightMax = maybe 100.0 _.weight $ A.last edgesWeightSorted
let edgeWeightRange = Range.Closed { min: edgeWeightMin, max: edgeWeightMax }
let edgesConfluenceSorted = A.sortWith (_.confluence) $ Seq.toUnfoldable $ SigmaxT.graphEdges graph let edgesConfluenceSorted = A.sortWith (_.confluence) $ Seq.toUnfoldable $ SigmaxT.graphEdges graph
let edgeConfluenceMin = maybe 0.0 _.confluence $ A.head edgesConfluenceSorted let edgeConfluenceMin = maybe 0.0 _.confluence $ A.head edgesConfluenceSorted
let edgeConfluenceMax = maybe 100.0 _.confluence $ A.last edgesConfluenceSorted let edgeConfluenceMax = maybe 100.0 _.confluence $ A.last edgesConfluenceSorted
...@@ -184,13 +188,17 @@ hydrateStoreCpt = here.component "hydrateStore" cpt where ...@@ -184,13 +188,17 @@ hydrateStoreCpt = here.component "hydrateStore" cpt where
let nodeSizeMax = maybe 100.0 _.size $ A.last nodesSorted let nodeSizeMax = maybe 100.0 _.size $ A.last nodesSorted
let nodeSizeRange = Range.Closed { min: nodeSizeMin, max: nodeSizeMax } let nodeSizeRange = Range.Closed { min: nodeSizeMin, max: nodeSizeMax }
let edgeWeight = Range.Closed -- let edgeWeight = Range.Closed
{ min: 0.0 -- { min: 0.0
, max: I.toNumber $ Seq.length $ SigmaxT.graphEdges graph -- , max: I.toNumber $ Seq.length $ SigmaxT.graphEdges graph
} -- }
-- let weightsSeq = Seq.map _.weight $ SigmaxT.graphEdges graph
-- let edgeWeight = Range.Closed
-- { min: fromMaybe 0.0 $ minimum weightsSeq
-- , max: fromMaybe 1.0 $ maximum weightsSeq } :: Range.Closed Number
let transformedGraph = transformGraph graph { edgeConfluence': GraphStore.options.edgeConfluence let transformedGraph = transformGraph graph { edgeConfluence': GraphStore.options.edgeConfluence
, edgeWeight': edgeWeight , edgeWeight': GraphStore.options.edgeWeight
, nodeSize': GraphStore.options.nodeSize , nodeSize': GraphStore.options.nodeSize
, removedNodeIds': GraphStore.options.removedNodeIds , removedNodeIds': GraphStore.options.removedNodeIds
, selectedNodeIds': GraphStore.options.selectedNodeIds , selectedNodeIds': GraphStore.options.selectedNodeIds
...@@ -208,7 +216,8 @@ hydrateStoreCpt = here.component "hydrateStore" cpt where ...@@ -208,7 +216,8 @@ hydrateStoreCpt = here.component "hydrateStore" cpt where
, startForceAtlas , startForceAtlas
, forceAtlasState , forceAtlasState
, noverlapState: SigmaxT.NoverlapPaused , noverlapState: SigmaxT.NoverlapPaused
, edgeWeight -- , edgeWeight
, edgeWeightRange
, edgeConfluenceRange , edgeConfluenceRange
, nodeSizeRange , nodeSizeRange
-- (cache options) -- (cache options)
......
...@@ -21,6 +21,7 @@ import DOM.Simple.Event as Event ...@@ -21,6 +21,7 @@ import DOM.Simple.Event as Event
import DOM.Simple.EventListener as EL import DOM.Simple.EventListener as EL
import DOM.Simple (DOMRect) import DOM.Simple (DOMRect)
import Effect (Effect) import Effect (Effect)
import Effect.Debouncing as Debounce
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T import Toestand as T
...@@ -51,6 +52,7 @@ type Props = ...@@ -51,6 +52,7 @@ type Props =
, width :: Number , width :: Number
, height :: Number , height :: Number
, onChange :: Range.NumberRange -> Effect Unit , onChange :: Range.NumberRange -> Effect Unit
, throttleInterval :: Maybe Int -- then Nothing, no throttling is done
, status :: ComponentStatus ) , status :: ComponentStatus )
data Knob = MinKnob | MaxKnob data Knob = MinKnob | MaxKnob
...@@ -65,6 +67,11 @@ rangeSlider props = R.createElement rangeSliderCpt props [] ...@@ -65,6 +67,11 @@ rangeSlider props = R.createElement rangeSliderCpt props []
rangeSliderCpt :: R.Component Props rangeSliderCpt :: R.Component Props
rangeSliderCpt = here.component "rangeSlider" cpt where rangeSliderCpt = here.component "rangeSlider" cpt where
cpt props _ = do cpt props _ = do
let throttled = Debounce.throttleWithDebounceAtEnd props.onChange (fromMaybe 0 props.throttleInterval)
let onChangeThrottled = case props.throttleInterval of
Nothing -> props.onChange
Just ti -> \rng -> Debounce.call throttled rng
-- rounding precision (i.e. how many decimal digits are in epsilon) -- rounding precision (i.e. how many decimal digits are in epsilon)
let (Range.Closed { min: minR, max: maxR }) = props.initialValue let (Range.Closed { min: minR, max: maxR }) = props.initialValue
let decPrecision num = let decPrecision num =
...@@ -116,7 +123,8 @@ rangeSliderCpt = here.component "rangeSlider" cpt where ...@@ -116,7 +123,8 @@ rangeSliderCpt = here.component "rangeSlider" cpt where
case reproject drag scalePos props.bounds props.epsilon (R2.domMousePosition event) of case reproject drag scalePos props.bounds props.epsilon (R2.domMousePosition event) of
Just val -> do Just val -> do
setKnob knob value value' val setKnob knob value value' val
props.onChange $ knobSetter knob value' val -- props.onChange $ knobSetter knob value' val
onChangeThrottled $ knobSetter knob value' val
Nothing -> destroy unit Nothing -> destroy unit
let onMouseUp = EL.callback $ \(_event :: Event.MouseEvent) -> do let onMouseUp = EL.callback $ \(_event :: Event.MouseEvent) -> do
--props.onChange $ knobSetter knob value val --props.onChange $ knobSetter knob value val
......
...@@ -61,4 +61,13 @@ export function _scrollIntoView(el) { ...@@ -61,4 +61,13 @@ export function _scrollIntoView(el) {
inline: 'center' inline: 'center'
}); });
} }
\ No newline at end of file
export const isPendingTransitionImpl = (t) => () => {
return t[0]();
}
export const startTransitionImpl = (t) => (f) => () => {
console.log('starting transition', t, f);
return t[1](() => { f()() });
}
...@@ -648,3 +648,24 @@ setInputValue elNullableRef val = case toMaybe (R.readRef elNullableRef) of ...@@ -648,3 +648,24 @@ setInputValue elNullableRef val = case toMaybe (R.readRef elNullableRef) of
_ <- pure $ (el .= "value") val _ <- pure $ (el .= "value") val
triggerEvent el "change" triggerEvent el "change"
triggerEvent el "input" triggerEvent el "input"
-- TODO useTransition?
foreign import data Transition :: Type
-- foreign import useTransitionImpl :: R.Hooks Transition
-- useTransition :: R.Hooks Transition
-- useTransition = useTransitionImpl
useTransition :: R.Hooks Transition
useTransition = hook $ \_ -> pure $ react ... "useTransition" $ []
foreign import isPendingTransitionImpl :: Transition -> R.Hooks Boolean
isPendingTransition :: Transition -> R.Hooks Boolean
isPendingTransition = isPendingTransitionImpl
foreign import startTransitionImpl :: Transition -> (Unit -> Effect Unit) -> Effect Unit
startTransition :: Transition -> (Unit -> Effect Unit) -> Effect Unit
startTransition = startTransitionImpl
...@@ -8,7 +8,7 @@ import Effect (Effect) ...@@ -8,7 +8,7 @@ import Effect (Effect)
import FFI.Simple ((...)) import FFI.Simple ((...))
import Gargantext.Components.App as App import Gargantext.Components.App as App
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Prelude (Unit, ($)) import Prelude (Unit, ($), bind)
import Reactix as R import Reactix as R
...@@ -21,6 +21,8 @@ main = paint $ toMaybe (document ... "getElementById" $ [ "app" ]) ...@@ -21,6 +21,8 @@ main = paint $ toMaybe (document ... "getElementById" $ [ "app" ])
paint :: Maybe Element -> Effect Unit paint :: Maybe Element -> Effect Unit
paint Nothing = here.error "[main] Container not found" paint Nothing = here.error "[main] Container not found"
paint (Just c) = do paint (Just c) = do
R.render app c -- R.render app c
let r = R.createRoot c
R.renderRoot r app
where where
app = App.app {} app = App.app {}
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