Commit 29252ba9 authored by Karen Konou's avatar Karen Konou

Merge branch '262-dev-phylo-search-documents' of...

Merge branch '262-dev-phylo-search-documents' of ssh://gitlab.iscpif.fr:20022/gargantext/purescript-gargantext into 262-dev-phylo-search-documents
parents b637f13b 29d81ed7
use nix
#use nix
use flake
......@@ -11,6 +11,7 @@ reports
node_modules
.DS_Store
/.direnv/
/bower_components/
/node_modules/
/.cache/
......
# Thanks to:
# https://vadosware.io/post/zero-to-continuous-integrated-testing-a-haskell-project-with-gitlab/
#
#
image: nixos/nix:latest
variables:
STACK_ROOT: "${CI_PROJECT_DIR}/.stack-root"
STACK_OPTS: "--system-ghc"
# Fixing the nixos image saves CI time so it doesn't have to pull new
#image every time (nixos/nix updates quite often).
# image: nixos/nix:latest
image: nixos/nix:2.22.0
#before_script:
#- nix-env -iA nixpkgs.nix nixpkgs.cacert
#- apt-get update
#- apt-get install make xz-utils
stages:
- deps
# - deps
- compile
- test
deps:
# deps:
# stage: deps
# cache:
# paths:
# - /nix/store
# #- node_modules/
# script:
# - nix-shell shell.nix --run 'bun install --skip-builds'
compile:
stage: compile
cache:
paths:
- /nix/store
- node_modules/
- output/
- .spago/
script:
- nix-env -i git
- nix-shell shell.nix --run 'yarn --skip-builds'
- nix --extra-experimental-features "nix-command flakes" run .#compile
test:
stage: test
cache:
# cache per branch name
# key: ${CI_COMMIT_REF_SLUG}
paths:
- /nix/store
- node_modules/
- output/
- .spago/
script:
# find 0.14.5 purescript version here:
# https://lazamar.co.uk/nix-versions/
- nix-env -i git
- nix-shell shell.nix --run 'yarn --skip-builds'
- nix-shell shell.nix --run test-ps
- nix --extra-experimental-features "nix-command flakes" run .#test-ps
- nix-collect-garbage --delete-older-than 14d
......@@ -52,13 +52,23 @@ $ nix-env --version
nix-env (Nix) 2.11.0
```
To build the frontend just execute the install script at the root at the project:
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:
```shell
./install
```
**Local instance is ready!** (Example: http://localhost:8000/)
```shell
nix -L develop
```
**Local instance is ready!** (Example: http://localhost:8000/)
### 2. Use Docker setup
......@@ -101,6 +111,6 @@ nix-shell --run build
To compile CSS (Sass):
```shell
nix-shell --run "yarn css"
nix-shell --run "npm run css"
```
// Main Gargantext scripts
$(function () {
$('[data-toggle="tooltip"]').tooltip()
console.log("Gargantext is ready.");
})
\ No newline at end of file
This diff is collapsed.
......@@ -6696,9 +6696,16 @@ a:hover {
font-family: ForkAwesome, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
.node-layout__title {
font-size: 1.75em;
}
.nav.nav-tabs .nav-link {
cursor: pointer;
}
.nav.nav-tabs .nav-link .active {
font-weight: 500;
}
.nav.nav-tabs .nav-tabs .nav-link.active, .nav.nav-tabs .nav-tabs .nav-item.show .nav-link, .nav.nav-tabs li a {
color: #DEE2E6;
}
......@@ -11991,6 +11998,19 @@ select.form-control {
.phylo-details-tab__counter__value {
font-weight: bold;
}
.phylo-details-tab__params {
margin: 16px 20px;
}
.phylo-details-tab__params__item {
margin-left: 16px;
list-style: initial;
}
.phylo-details-tab__params__label {
font-weight: bold;
}
.phylo-details-tab__params__value {
margin-left: 16px;
}
.phylo-details-tab__delimiter {
margin: 16px 20px;
}
......
......@@ -6507,9 +6507,16 @@ a:hover {
font-family: ForkAwesome, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
.node-layout__title {
font-size: 1.75em;
}
.nav.nav-tabs .nav-link {
cursor: pointer;
}
.nav.nav-tabs .nav-link .active {
font-weight: 500;
}
.nav.nav-tabs .nav-tabs .nav-link.active, .nav.nav-tabs .nav-tabs .nav-item.show .nav-link, .nav.nav-tabs li a {
color: #495057;
}
......@@ -11795,6 +11802,19 @@ select.form-control {
.phylo-details-tab__counter__value {
font-weight: bold;
}
.phylo-details-tab__params {
margin: 16px 20px;
}
.phylo-details-tab__params__item {
margin-left: 16px;
list-style: initial;
}
.phylo-details-tab__params__label {
font-weight: bold;
}
.phylo-details-tab__params__value {
margin-left: 16px;
}
.phylo-details-tab__delimiter {
margin: 16px 20px;
}
......
......@@ -6350,9 +6350,16 @@ a:hover {
font-family: ForkAwesome, "Mulish";
}
.node-layout__title {
font-size: 1.75em;
}
.nav.nav-tabs .nav-link {
cursor: pointer;
}
.nav.nav-tabs .nav-link .active {
font-weight: 500;
}
.nav.nav-tabs .nav-tabs .nav-link.active, .nav.nav-tabs .nav-tabs .nav-item.show .nav-link, .nav.nav-tabs li a {
color: #495057;
}
......@@ -11645,6 +11652,19 @@ select.form-control {
.phylo-details-tab__counter__value {
font-weight: bold;
}
.phylo-details-tab__params {
margin: 16px 20px;
}
.phylo-details-tab__params__item {
margin-left: 16px;
list-style: initial;
}
.phylo-details-tab__params__label {
font-weight: bold;
}
.phylo-details-tab__params__value {
margin-left: 16px;
}
.phylo-details-tab__delimiter {
margin: 16px 20px;
}
......
......@@ -6571,9 +6571,16 @@ a:hover {
font-family: ForkAwesome, "Nunito";
}
.node-layout__title {
font-size: 1.75em;
}
.nav.nav-tabs .nav-link {
cursor: pointer;
}
.nav.nav-tabs .nav-link .active {
font-weight: 500;
}
.nav.nav-tabs .nav-tabs .nav-link.active, .nav.nav-tabs .nav-tabs .nav-item.show .nav-link, .nav.nav-tabs li a {
color: #495057;
}
......@@ -11866,6 +11873,19 @@ select.form-control {
.phylo-details-tab__counter__value {
font-weight: bold;
}
.phylo-details-tab__params {
margin: 16px 20px;
}
.phylo-details-tab__params__item {
margin-left: 16px;
list-style: initial;
}
.phylo-details-tab__params__label {
font-weight: bold;
}
.phylo-details-tab__params__value {
margin-left: 16px;
}
.phylo-details-tab__delimiter {
margin: 16px 20px;
}
......
......@@ -6644,9 +6644,16 @@ a:hover {
font-family: ForkAwesome, "Montserrat";
}
.node-layout__title {
font-size: 1.75em;
}
.nav.nav-tabs .nav-link {
cursor: pointer;
}
.nav.nav-tabs .nav-link .active {
font-weight: 500;
}
.nav.nav-tabs .nav-tabs .nav-link.active, .nav.nav-tabs .nav-tabs .nav-item.show .nav-link, .nav.nav-tabs li a {
color: #495057;
}
......@@ -11939,6 +11946,19 @@ select.form-control {
.phylo-details-tab__counter__value {
font-weight: bold;
}
.phylo-details-tab__params {
margin: 16px 20px;
}
.phylo-details-tab__params__item {
margin-left: 16px;
list-style: initial;
}
.phylo-details-tab__params__label {
font-weight: bold;
}
.phylo-details-tab__params__value {
margin-left: 16px;
}
.phylo-details-tab__delimiter {
margin: 16px 20px;
}
......
{
"nodes": {
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1701282334,
"narHash": "sha256-MxCVrXY6v4QmfTwIysjjaX0XUhqBbxTWWB4HXtDYsdk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "057f9aecfb71c4437d2b27d3323df7f93c010b7e",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"type": "github"
}
},
"purescript-overlay": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": [
"nixpkgs"
],
"slimlock": "slimlock"
},
"locked": {
"lastModified": 1713366964,
"narHash": "sha256-s1WUptOTTAQ3aW6JlIpDgWofoQF5vp7q8ItbTeSxLL4=",
"owner": "thomashoneyman",
"repo": "purescript-overlay",
"rev": "235afffdb751d83c7775b334e5be944848fc24ad",
"type": "github"
},
"original": {
"owner": "thomashoneyman",
"repo": "purescript-overlay",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"purescript-overlay": "purescript-overlay"
}
},
"slimlock": {
"inputs": {
"nixpkgs": [
"purescript-overlay",
"nixpkgs"
]
},
"locked": {
"lastModified": 1688756706,
"narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=",
"owner": "thomashoneyman",
"repo": "slimlock",
"rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c",
"type": "github"
},
"original": {
"owner": "thomashoneyman",
"repo": "slimlock",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}
{
description = "Gargantext PureScript fronetnd";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.nixpkgs.url = "github:NixOS/nixpkgs";
inputs.purescript-overlay = {
url = "github:thomashoneyman/purescript-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, flake-utils, purescript-overlay }:
flake-utils.lib.eachDefaultSystem (system:
#let pkgs = nixpkgs.legacyPackages.${system};
let
pkgs = import nixpkgs {
inherit system;
overlays = [ purescript-overlay.overlays.default ];
};
dependencies = with pkgs; [
purescript
#spago-unstable
nodejs
nodePackages.npm
];
serve = pkgs.writeShellScriptBin "serve" ''
set -e
#yarn server
npm run server
'';
build-watch = pkgs.writeShellScriptBin "build-watch" ''
set -e
echo "Build watch"
npm spago build -w --then browserify
'';
build-zephyr = pkgs.writeShellScriptBin "build-zephyr" ''
set -e
npm spago build --purs-args '--codegen corefn,js'
zephyr -f Main.main
browserify-zephyr
'';
minify-bundle = pkgs.writeShellScriptBin "minify-bundle" ''
set -e
npm run minify
'';
in
{
packages = rec {
compile = pkgs.writeShellApplication {
name = "compile";
runtimeInputs = dependencies;
text = ''
set -e
echo "Installing JS Dependencies"
#npm install
# https://docs.npmjs.com/cli/v9/commands/npm-ci
npm ci
#npm/bin/npm install --dev
echo "Compiling"
npm run build
'';
};
build = pkgs.writeShellApplication {
name = "build";
runtimeInputs = [ compile ] ++ dependencies;
text = ''
set -e
compile
echo "Bundling"
npm run bundle
'';
};
test-ps = pkgs.writeShellApplication {
name = "test-ps";
runtimeInputs = [ compile ] ++ dependencies;
text = ''
set -e
compile
echo "Testing"
npm run test
'';
};
repl = pkgs.writeShellApplication {
name = "repl";
runtimeInputs = [ compile ] ++ dependencies;
text = ''
npm run repl
'';
};
build-css = pkgs.writeShellApplication {
name = "build-css";
runtimeInputs = [ compile ] ++ dependencies;
text = ''
set -e
#yarn css
npm run css
'';
};
};
devShells.default = pkgs.mkShell {
name = "purescript-gargantext";
#inputsFrom = builtins.attrValues self.packages.${system};
buildInputs = with pkgs; (dependencies ++ [
# scripts
self.packages.${system}.build
self.packages.${system}.compile
self.packages.${system}.test-ps
self.packages.${system}.repl
self.packages.${system}.build-css
build-watch
build-zephyr
minify-bundle
serve
]);
};
}
);
}
......@@ -3,6 +3,10 @@
# To get infos
# nix-shell -p nix-info --run "nix-info -m"
nix-channel --update
nix-env -iA nixpkgs.nix nixpkgs.cacert
nix-shell --show-trace --option build-fallback true --run build
# nix-channel --update
# nix-env -iA nixpkgs.nix nixpkgs.cacert
# nix-shell --show-trace --option build-fallback true --run 'bun install'
# nix-shell --show-trace --option build-fallback true --run fix-bun
# nix-shell --show-trace --option build-fallback true --run build
#nix run .#install
nix run .#build
......@@ -5,8 +5,8 @@ import
pkgs.fetchFromGitHub {
owner = "justinwoo";
repo = "easy-purescript-nix";
rev = "11d3bd58ce6e32703bf69cec04dc7c38eabe14ba";
sha256 = "tESal32bcqqdZO+aKnBzc1GoL2mtnaDtj2y7ociCRGA=";
rev = "117fd96acb69d7d1727df95b6fde9d8715e031fc";
sha256 = "lcIRIOFCdIWEGyKyG/tB4KvxM9zoWuBRDxW+T+mvIb0=";
}
) {
inherit pkgs;
......
Avoids needing xcrun or xcodebuild in PATH for native package builds
diff --git a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
index a75d8ee..476440d 100644
--- a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
+++ b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py
@@ -522,7 +522,13 @@ class XcodeSettings:
# Since the CLT has no SDK paths anyway, returning None is the
# most sensible route and should still do the right thing.
try:
- return GetStdoutQuiet(["xcrun", "--sdk", sdk, infoitem])
+ #return GetStdoutQuiet(["xcrun", "--sdk", sdk, infoitem])
+ return {
+ "--show-sdk-platform-path": "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform",
+ "--show-sdk-path": "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk",
+ "--show-sdk-build-version": "19A547",
+ "--show-sdk-version": "10.15"
+ }[infoitem]
except GypError:
pass
@@ -1499,7 +1505,8 @@ def XcodeVersion():
version = ""
build = ""
try:
- version_list = GetStdoutQuiet(["xcodebuild", "-version"]).splitlines()
+ #version_list = GetStdoutQuiet(["xcodebuild", "-version"]).splitlines()
+ version_list = []
# In some circumstances xcodebuild exits 0 but doesn't return
# the right results; for example, a user on 10.7 or 10.8 with
# a bogus path set via xcode-select
@@ -1510,7 +1517,8 @@ def XcodeVersion():
version = version_list[0].split()[-1] # Last word on first line
build = version_list[-1].split()[-1] # Last word on last line
except GypError: # Xcode not installed so look for XCode Command Line Tools
- version = CLTVersion() # macOS Catalina returns 11.0.0.0.1.1567737322
+ #version = CLTVersion() # macOS Catalina returns 11.0.0.0.1.1567737322
+ version = "11.0.0.0.1.1567737322"
if not version:
raise GypError("No Xcode or CLT version detected!")
# Be careful to convert "4.2.3" to "0423" and "11.0.0" to "1100":
Disable v8 system instrumentation on Darwin
On Darwin, the v8 system instrumentation requires the header "os/signpost.h"
which is available since apple_sdk 11+. See: https://github.com/nodejs/node/issues/39584
--- old/tools/v8_gypfiles/features.gypi
+++ new/tools/v8_gypfiles/features.gypi
@@ -62,7 +62,7 @@
}, {
'is_component_build': 0,
}],
- ['OS == "win" or OS == "mac"', {
+ ['OS == "win"', {
# Sets -DENABLE_SYSTEM_INSTRUMENTATION. Enables OS-dependent event tracing
'v8_enable_system_instrumentation': 1,
}, {
This patch is based off of npm tag v9.1.5.
This introduces fixes for 4 issues:
1. When node-gyp is included as a dependency in a project, any scripts that run it will not use the copy included in Node. This is problematic because we patch node-gyp to work without xcbuild on Darwin, leading to these packages failing to build with a sandbox on Darwin.
2. When a Git dependency contains install scripts, it has to be built just like any other package. Thus, we need to patch shebangs appropriately, just like in npmConfigHook.
3. We get useless warnings that clog up logs when using a v1 lockfile, so we silence them.
4. npm looks at a hidden lockfile to determine if files have binaries to link into `node_modules/.bin`. When using a v1 lockfile offline, this lockfile does not contain enough info, leading to binaries for packages such as Webpack not being available to scripts. We used to work around this by making npm ignore the hidden lockfile by creating a file, but now we just disable the code path entirely.
To update:
1. Run `git diff` from an npm checkout
2. Run `fix-npm-patch-paths.sh`
3. Include/update this frontmatter, please!
diff --git a/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js b/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js
index c59c270d9..98785192f 100644
--- a/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js
+++ b/deps/npm/node_modules/@npmcli/run-script/lib/set-path.js
@@ -12,7 +12,10 @@ const setPATH = (projectPath, binPaths, env) => {
.reduce((set, p) => set.concat(p.filter(concatted => !set.includes(concatted))), [])
.join(delimiter)
- const pathArr = []
+ // Ensure when using buildNpmPackage hooks that Node.js'
+ // bundled copy of node-gyp is used, instead of any copy
+ // pulled in as a dependency.
+ const pathArr = process.env['NIX_NODEJS_BUILDNPMPACKAGE'] ? [nodeGypPath, PATH] : [];
if (binPaths) {
pathArr.push(...binPaths)
}
@@ -26,7 +29,8 @@ const setPATH = (projectPath, binPaths, env) => {
pp = p
p = dirname(p)
} while (p !== pp)
- pathArr.push(nodeGypPath, PATH)
+ if (!process.env['NIX_NODEJS_BUILDNPMPACKAGE']) { pathArr.push(nodeGypPath, PATH) }
+
const pathVal = pathArr.join(delimiter)
diff --git a/deps/npm/node_modules/pacote/lib/git.js b/deps/npm/node_modules/pacote/lib/git.js
index 1fa8b1f96..a026bb50d 100644
--- a/deps/npm/node_modules/pacote/lib/git.js
+++ b/deps/npm/node_modules/pacote/lib/git.js
@@ -188,6 +188,24 @@ class GitFetcher extends Fetcher {
}
noPrepare.push(this.resolved)
+ if (process.env['NIX_NODEJS_BUILDNPMPACKAGE']) {
+ const spawn = require('@npmcli/promise-spawn')
+
+ const npmWithNixFlags = (args, cmd) => spawn('bash', ['-c', 'npm ' + args + ` $npm${cmd}Flags "$\{npm${cmd}FlagsArray[@]}" $npmFlags "$\{npmFlagsArray[@]}"`], { cwd: dir, env: { ...process.env, _PACOTE_NO_PREPARE_: noPrepare.join('\n') } }, { message: `\`npm ${args}\` failed` })
+ const patchShebangs = () => spawn('bash', ['-c', 'source $stdenv/setup; patchShebangs node_modules'], { cwd: dir })
+
+ // the DirFetcher will do its own preparation to run the prepare scripts
+ // All we have to do is put the deps in place so that it can succeed.
+ //
+ // We ignore this.npmConfig to maintain an environment that's as close
+ // to the rest of the build as possible.
+ return spawn('bash', ['-c', '$prefetchNpmDeps --fixup-lockfile package-lock.json'], { cwd: dir })
+ .then(() => npmWithNixFlags('ci --ignore-scripts', 'Install'))
+ .then(patchShebangs)
+ .then(() => npmWithNixFlags('rebuild', 'Rebuild'))
+ .then(patchShebangs)
+ }
+
// the DirFetcher will do its own preparation to run the prepare scripts
// All we have to do is put the deps in place so that it can succeed.
return npm(
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js
index 2ea66ac33..25e671318 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js
@@ -740,7 +740,7 @@ This is a one-time fix-up, please be patient...
node.package = { ...mani, _id: `${mani.name}@${mani.version}` }
} catch (er) {
const warning = `Could not fetch metadata for ${name}@${id}`
- log.warn(heading, warning, er)
+ if (!process.env['NIX_NODEJS_BUILDNPMPACKAGE']) { log.warn(heading, warning, er) }
}
this.finishTracker(t)
})
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js
index 6c3f917c6..ec21d2cc4 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-actual.js
@@ -147,7 +147,7 @@ module.exports = cls => class ActualLoader extends cls {
this[_actualTree].assertRootOverrides()
// if forceActual is set, don't even try the hidden lockfile
- if (!forceActual) {
+ if (!forceActual && !process.env['NIX_NODEJS_BUILDNPMPACKAGE']) {
// Note: hidden lockfile will be rejected if it's not the latest thing
// in the folder, or if any of the entries in the hidden lockfile are
// missing.
Fixes cross compilation to aarch64-linux by reverting
https://github.com/nodejs/node/pull/43200
--- old/configure.py
+++ new/configure.py
@@ -1236,7 +1236,6 @@
# Enable branch protection for arm64
if target_arch == 'arm64':
- o['cflags']+=['-msign-return-address=all']
o['variables']['arm_fpu'] = options.arm_fpu or 'neon'
if options.node_snapshot_main is not None:
{ callPackage, openssl, python3, enableNpm ? true, nodejs, path }:
let
buildNodejs = callPackage "${path}/pkgs/development/web/nodejs/nodejs.nix" {
inherit openssl;
python = python3;
};
in
buildNodejs {
inherit enableNpm;
version = "20.3.1";
sha256 = "sha256-EqgtswZpeVm0OJs1Gl+XhImGsTE/mQGw4LPYz08/mZE=";
patches = [
./nodejs-patches/revert-arm64-pointer-auth.patch
./nodejs-patches/disable-darwin-v8-system-instrumentation-node19.patch
./nodejs-patches/bypass-darwin-xcrun-node16.patch
./nodejs-patches/node-npm-build-npm-package-logic.patch
];
}
import (
builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/23.05.tar.gz";
url = "https://github.com/NixOS/nixpkgs/archive/23.11.tar.gz";
}
)
File moved
File moved
File moved
......@@ -2,51 +2,46 @@
let
easy-ps = import ./nix/easy-ps.nix { inherit pkgs; };
purs-packages = import ./purs-packages.nix { inherit pkgs; };
purs-project = import ./nix/purs-project.nix { inherit pkgs; };
build-purs = pkgs.writeShellScriptBin "build-purs" ''
# sometimes bun is broken because of better-sqlite3
fix-bun = pkgs.writeShellScriptBin "fix-bun" ''
#!/usr/bin/env bash
purs compile ${toString purs-project.sourceGlobs} "src/**/*.purs" "test/**/*.purs"
'';
set -e
build = pkgs.writeShellScriptBin "build" ''
cd ./node_modules/better-sqlite3
bun install
'';
compile = pkgs.writeShellScriptBin "compile" ''
#!/usr/bin/env bash
set -e
echo "Installing JS Dependencies"
yarn
#yarn
bun install
bun install --dev
echo "Compiling"
#build-purs
#spago build
#echo "Bundling"
#pulp browserify --skip-compile -t dist/bundle.js --src-path output
#browserify
bun run build
'';
build = pkgs.writeShellScriptBin "build" ''
#!/usr/bin/env bash
set -e
# 0.15
spago bundle-app --main Main --to dist/bundle.js
echo "Bundling"
bun run bundle
'';
build-suggestions = pkgs.writeShellScriptBin "build-suggestions" ''
#!/usr/bin/env bash
set -e
echo "Installing JS Dependencies"
yarn
rm -rf ./output
echo "Compiling"
#build-purs
#spago build
#echo "Bundling"
#pulp browserify --skip-compile -t dist/bundle.js --src-path output
#browserify
# 0.15
spago bundle-app --main Main --to dist/bundle.js --purs-args "--json-errors" | jq -r '.warnings | map(select(.errorCode | test("UnusedDctorExplicitImport|UnusedDctorImport|UnusedDeclaration|UnusedExplicitImport|UnusedImport|UnusedName|UnusedTypeVar"))) | map(select(.filename | test("^.spago") | not)) | map("[\(.filename)::\(.position.startLine)] \(.message)\n \(.suggestion)") | join("\n----------\n")'
echo "Bundling"
bun spago bundle --module Main --outfile dist/bundle.js --purs-args "--json-errors" | jq -r '.warnings | map(select(.errorCode | test("UnusedDctorExplicitImport|UnusedDctorImport|UnusedDeclaration|UnusedExplicitImport|UnusedImport|UnusedName|UnusedTypeVar"))) | map(select(.filename | test("^.spago") | not)) | map("[\(.filename)::\(.position.startLine)] \(.message)\n \(.suggestion)") | join("\n----------\n")'
'';
......@@ -54,15 +49,16 @@ let
#!/usr/bin/env bash
set -e
yarn css
#yarn css
bun run css
'';
serve = pkgs.writeShellScriptBin "serve" ''
#!/usr/bin/env bash
set -e
yarn server
#yarn server
bun run server
'';
......@@ -71,101 +67,74 @@ let
set -e
echo "Build watch"
spago build -w --then browserify
bun spago build -w --then browserify
'';
build-zephyr = pkgs.writeShellScriptBin "build-zephyr" ''
#!/usr/bin/env bash
set -e
spago build --purs-args '--codegen corefn,js'
bun spago build --purs-args '--codegen corefn,js'
zephyr -f Main.main
browserify-zephyr
'';
browserify = pkgs.writeShellScriptBin "browserify" ''
#!/usr/bin/env bash
set -e
pulp browserify --skip-compile -t dist/bundle.js --src-path output
'';
browserify-zephyr = pkgs.writeShellScriptBin "browserify-zephyr" ''
#!/usr/bin/env bash
set -e
pulp browserify --skip-compile -t dist/bundle.js -o dce-output
#purs bundle -o dist/bundle.js -m Main dce-output/**/*.js
'';
minify-bundle = pkgs.writeShellScriptBin "minify-bundle" ''
#!/usr/bin/env bash
set -e
minify dist/bundle.js > dist/bundle.min.js
bun run minify
'';
repl = pkgs.writeShellScriptBin "repl" ''
#!/usr/bin/env bash
spago repl
bun run repl
'';
test-ps = pkgs.writeShellScriptBin "test-ps" ''
#!/usr/bin/env bash
set -e
echo "Compiling"
yarn
#spago build
#build-purs
compile
echo "Testing"
spago -v -x test.dhall test --main Test.Main
# spago -x test.dhall bundle-app --main Test.Main --to dist/test-bundle.js --platform node
# pulp browserify --skip-compile -t dist/bundle.js --src-path output
# pulp test --src-path output --test-path output
#NODE_PATH=output node -e "require('Test.Main').main();"
bun run test
'';
# TODO: Remove this when nixpkgs is updated to newer version (23.05
# has nodejs 20.2.1 and we need >= 20.3.1 for crypto to work)
#nodejs_20_3_1 = pkgs.callPackage ./nix/nodejs-v20.nix {};
in
pkgs.mkShell {
buildInputs = [
easy-ps.purs-0_15_7
easy-ps.psc-package
easy-ps.dhall-json-simple
easy-ps.purs-0_15_15
easy-ps.zephyr
browserify
browserify-zephyr
pkgs.ijq
pkgs.jq
#pkgs.esbuild
pkgs.nodejs
#pkgs.yarn
pkgs.bun
pkgs.sqlite
# scripts
build-css
build-purs
build-suggestions
build-watch
build-zephyr
build
pkgs.ijq
pkgs.jq
compile
fix-bun
minify-bundle
#pkgs.closurecompiler
pkgs.esbuild
pkgs.minify
pkgs.nodejs
#pkgs.nodePackages.purescript-language-server
#pkgs.python # needed for msgpack etc
#nodejs_20_3_1
repl
serve
pkgs.pulp
pkgs.spago
pkgs.yarn
test-ps
];
shellHook = ''
export PURS_IDE_SOURCES='${toString purs-project.unquotedSourceGlobs}'
'';
#shellHook = ''
# export PURS_IDE_SOURCES='${toString purs-project.unquotedSourceGlobs}'
#'';
}
## how to build the project with nix dependencies:
......
This diff is collapsed.
{
"name": "Gargantext",
"version": "0.0.7.1.1",
"scripts": {
"generate-purs-packages-nix": "./nix/generate-purs-packages.nix",
"generate-psc-packages-nix": "./nix/generate-packages-json.bash",
"css": "yarn css-themes",
"css-themes": "yarn css-default-theme && yarn css-dark-theme && yarn css-darkster-theme && yarn css-greyson-theme && yarn css-herbie-theme && yarn css-monotony-theme",
"css-default-theme": "sass src/sass/themes/default.scss:dist/styles/bootstrap-default.css",
"css-dark-theme": "cp node_modules/bootstrap-dark/src/bootstrap-dark.css dist/styles/bootstrap-dark.css",
"css-darkster-theme": "sass src/sass/themes/darkster.scss:dist/styles/bootstrap-darkster.css",
"css-greyson-theme": "sass src/sass/themes/greyson.scss:dist/styles/bootstrap-greyson.css",
"css-herbie-theme": "sass src/sass/themes/herbie.scss:dist/styles/bootstrap-herbie.css",
"css-monotony-theme": "sass src/sass/themes/monotony.scss:dist/styles/bootstrap-monotony.css",
"css-npm": "npm run css-themes-npm",
"css-themes-npm": "npm run css-default-theme && npm run css-dark-theme && npm run css-darkster-theme && npm run css-greyson-theme && npm run css-herbie-theme && npm run css-monotony-theme",
"docs": "pulp docs -- --format html",
"repl": "pulp repl",
"clean": "rm -Rf output node_modules",
"clean-js": "rm -Rf node_modules",
"clean-ps": "rm -Rf output",
"server": "serve -l 8008 dist",
"server-ssl": "ssl-serve --ssl dist",
"build": "spago bundle-app --main Main --to dist/bundle.js",
"prod": "yarn prod:compile && yarn prod:dce && yarn prod:bundle && yarn prod:pack",
"prod:compile": "pulp build -- -g corefn",
"prod:dce": "zephyr -f Main.main",
"prod:bundle": "pulp browserify --skip-compile -o dce-output -t app.js",
"prod:pack": "parcel build index.html -d prod --public-url . --no-source-maps",
"test-pulp": "pulp test",
"test": "gauge run specs/"
},
"dependencies": {
"@fontsource/crete-round": "^5.0.12",
"@fontsource/montserrat": "^5.0.17",
"@fontsource/mulish": "^5.0.16",
"@fontsource/nunito": "^5.0.17",
"@fontsource/open-sans": "^5.0.25",
"@fontsource/oswald": "^5.0.18",
"@popperjs/core": "^2.9.2",
"@urql/core": "^2.3.3",
"aes-js": "^3.1.1",
"base-x": "^3.0.2",
"bootstrap": "^4.6.0",
"bootstrap-dark": "^1.0.3",
"buffer": "^6.0.3",
"create-react-class": "^15.6.3",
"crypto": "^1.0.1",
"d3": "^7.6.1",
"echarts": "^5.1.2",
"echarts-for-react": "^3.0.1",
"esbuild": "^0.15.7",
"graphology": "^0.25.1",
"graphology-communities-louvain": "^2.0.1",
"graphology-layout-forceatlas2": "^0.9.2",
"graphology-layout-noverlap": "^0.4.2",
"graphology-operators": "^1.6.0",
"graphql": "^15.6.1",
"graphql-ws": "^5.5.0",
"highlightjs": "^9.16.2",
"immer": "^9.0.5",
"isomorphic-unfetch": "^3.1.0",
"markdown-it": "^13.0.1",
"prop-types": "^15.6.2",
"pullstate": "^1.20.6",
"react-awesome-popover": "^6.1.1",
"react-bootstrap": "^1.5.2",
"react-dom": "^17.0.2",
"react-tooltip": "^4.2.8",
"secp256k1": "^4.0.2",
"sigma": "^2.4.0",
"twgl.js": "^5.0.4",
"uuid": "8.3.2"
},
"devDependencies": {
"@babel/core": "^7.15.0",
"@babel/preset-env": "^7.15.6",
"@babel/preset-react": "^7.12.7",
"@getgauge/cli": "^1.4.0",
"parcel": "^2.8.2",
"react-testing-library": "^8.0.1",
"sass": "^1.35.2",
"serve": "^12.0.0",
"spago": "^0.20.9",
"ssl-serve": "^6.5.8",
"taiko": "latest",
"vscode-languageserver": "^7.0.0",
"xhr2": "^0.2.1"
},
"optionalDependencies": {
"purescript-language-server": "^0.17.1"
}
"name": "Gargantext",
"version": "0.0.7.1.6.1",
"scripts": {
"build": "spago build",
"bundle": "spago bundle --module Main --outfile dist/bundle.js",
"css": "$npm_execpath css-themes",
"css-themes": "$npm_execpath css-default-theme && $npm_execpath css-dark-theme && $npm_execpath css-darkster-theme && $npm_execpath css-greyson-theme && $npm_execpath css-herbie-theme && $npm_execpath css-monotony-theme",
"css-default-theme": "sass src/sass/themes/default.scss:dist/styles/bootstrap-default.css",
"css-dark-theme": "cp node_modules/bootstrap-dark/src/bootstrap-dark.css dist/styles/bootstrap-dark.css",
"css-darkster-theme": "sass src/sass/themes/darkster.scss:dist/styles/bootstrap-darkster.css",
"css-greyson-theme": "sass src/sass/themes/greyson.scss:dist/styles/bootstrap-greyson.css",
"css-herbie-theme": "sass src/sass/themes/herbie.scss:dist/styles/bootstrap-herbie.css",
"css-monotony-theme": "sass src/sass/themes/monotony.scss:dist/styles/bootstrap-monotony.css",
"docs": "spago docs",
"minify": "spago bundle --module Main --outfile dist/bundle.min.js --minify",
"repl": "spago repl",
"server": "serve -l 8008 dist",
"server-ssl": "ssl-serve --ssl dist",
"test": "spago test"
},
"dependencies": {
"@fontsource/crete-round": "~5.0.12",
"@fontsource/montserrat": "~5.0.17",
"@fontsource/mulish": "^5.0.16",
"@fontsource/nunito": "^5.0.17",
"@fontsource/open-sans": "~5.0.25",
"@fontsource/oswald": "~5.0.18",
"@popperjs/core": "~2.9.2",
"@urql/core": "~2.3.3",
"aes-js": "~3.1.1",
"base-x": "~3.0.2",
"bootstrap": "~4.6.0",
"bootstrap-dark": "~1.0.3",
"buffer": "~6.0.3",
"create-react-class": "~15.6.3",
"crypto": "~1.0.1",
"d3": "~7.6.1",
"debounce": "^2.0.0",
"debouncing": "^22.7.25",
"echarts": "~5.1.2",
"echarts-for-react": "~3.0.1",
"graphology": "~0.25.1",
"graphology-communities-louvain": "~2.0.1",
"graphology-layout-forceatlas2": "~0.9.2",
"graphology-layout-noverlap": "~0.4.2",
"graphology-operators": "~1.6.0",
"graphql": "~15.6.1",
"graphql-ws": "~5.5.0",
"highlightjs": "~9.16.2",
"immer": "~9.0.5",
"isomorphic-unfetch": "~3.1.0",
"markdown-it": "~13.0.1",
"prop-types": "~15.6.2",
"react": "~18.2.0",
"react-awesome-popover": "~6.1.1",
"react-bootstrap": "~1.5.2",
"react-dom": "~18.2.0",
"react-tooltip": "~4.2.8",
"secp256k1": "~4.0.2",
"sigma": "~2.4.0",
"twgl.js": "~5.0.4",
"use-debounce": "^10.0.0",
"uuid": "8.3.2"
},
"devDependencies": {
"@babel/core": "~7.24.5",
"@babel/preset-env": "~7.24.5",
"@babel/preset-react": "~7.24.1",
"@getgauge/cli": "~1.4.0",
"esbuild": "~0.21.1",
"parcel": "~2.8.2",
"react-testing-library": "~8.0.1",
"sass": "~1.77.0",
"serve": "~14.2.3",
"spago": "~0.93.29",
"ssl-serve": "~6.5.8",
"taiko": "latest",
"vscode-languageserver": "~7.0.0",
"xhr2": "~0.2.1"
},
"optionalDependencies": {
"purescript-language-server": "~0.17.1"
}
}
let upstream =
https://github.com/garganscript/package-sets/releases/download/v0.1.7/release.dhall
sha256:52886309e1f0158a85427f80c1e3d47ce747c5f14fcec671a81fe5c2c711a6db
let overrides =
{ graphql-client =
{ dependencies =
[ "aff"
, "aff-promise"
, "affjax"
, "affjax-node"
, "affjax-web"
, "argonaut-codecs"
, "argonaut-core"
, "arrays"
, "bifunctors"
, "control"
, "datetime"
, "debug"
, "effect"
, "either"
, "enums"
, "exceptions"
, "foldable-traversable"
, "foreign"
, "foreign-object"
, "functions"
, "halogen-subscriptions"
, "heterogeneous"
, "http-methods"
, "integers"
, "lists"
, "maybe"
, "media-types"
, "newtype"
, "node-buffer"
, "node-fs"
, "nullable"
, "numbers"
, "ordered-collections"
, "parsing"
, "prelude"
, "profunctor"
, "profunctor-lenses"
, "psci-support"
, "quickcheck"
, "record"
, "spec"
, "spec-discovery"
, "string-parsers"
, "strings"
, "strings-extra"
, "transformers"
, "tuples"
, "unicode"
, "unsafe-coerce"
, "variant"
]
, repo =
"https://github.com/OxfordAbstracts/purescript-graphql-client.git"
, version = "v9.2.2"
}
, jest =
{ dependencies =
[ "aff"
, "aff-promise"
, "effect"
, "foldable-traversable"
, "prelude"
, "psci-support"
]
, repo = "https://github.com/nonbili/purescript-jest"
, version = "018543987af27db6a3842048b6b3f5ec47609087"
}
, markdown-it =
{ dependencies =
[ "effect"
, "foldable-traversable"
, "foreign"
, "jest"
, "options"
, "prelude"
, "tuples"
]
, repo = "https://github.com/nonbili/purescript-markdown-it"
, version = "f6e8ee91298f2fc13c4277e75a19e0538de5f7a2"
}
, record-extra =
{ dependencies =
[ "arrays"
, "effect"
, "functions"
, "lists"
, "maybe"
, "prelude"
, "record"
, "test-unit"
, "tuples"
, "typelevel-prelude"
]
, repo = "https://github.com/justinwoo/purescript-record-extra"
, version = "v5.0.1"
}
}
let additions =
{ convertable-options =
{ dependencies = [ "console", "effect", "maybe", "record" ]
, repo = "https://github.com/natefaubion/purescript-convertable-options"
, version = "v1.0.0"
}
, data-default =
{ dependencies =
[ "assert", "lists", "maybe", "record", "effect", "prelude" ]
, repo = "https://github.com/thought2/purescript-data-default"
, version = "350e600a5a022c9599865a2dd14196b442f59bcc"
}
, dom-filereader =
{ dependencies = [ "aff", "arraybuffer-types", "web-file", "web-html" ]
, repo = "https://github.com/nwolverson/purescript-dom-filereader"
, version = "v5.0.0"
}
, sequences =
{ dependencies =
[ "arrays"
, "assert"
, "console"
, "control"
, "effect"
, "lazy"
, "maybe"
, "newtype"
, "nonempty"
, "partial"
, "prelude"
, "profunctor"
, "psci-support"
, "tuples"
, "unfoldable"
, "unsafe-coerce"
]
, repo = "https://github.com/garganscript/purescript-sequences.git"
, version = "recursion-fix"
}
, read =
{ dependencies = [ "prelude", "maybe", "strings" ]
, repo = "https://github.com/truqu/purescript-read"
, version = "v1.0.1"
}
, simple-json-generics =
{ dependencies =
[ "assert"
, "control"
, "effect"
, "either"
, "foreign"
, "partial"
, "prelude"
, "simple-json"
, "transformers"
, "typelevel-prelude"
]
, repo =
"https://github.com/garganscript/purescript-simple-json-generics"
, version = "master"
}
, spec-discovery =
{ dependencies = [ "prelude", "effect", "arrays", "spec", "node-fs" ]
, repo = "https://github.com/purescript-spec/purescript-spec-discovery"
, version = "v8.0.0"
}
, spec-quickcheck =
{ dependencies = [ "prelude", "aff", "random", "quickcheck", "spec" ]
, repo = "https://github.com/purescript-spec/purescript-spec-quickcheck"
, version = "v3.1.0"
}
, string-search =
{ dependencies =
[ "arrays"
, "enums"
, "foldable-traversable"
, "int64"
, "integers"
, "lists"
, "maybe"
, "ordered-collections"
, "partial"
, "prelude"
, "strings"
, "tuples"
, "uint"
]
, repo =
"https://gitlab.iscpif.fr/gargantext/purescript-string-search.git"
, version = "v0.1.6"
}
, tuples-native =
{ dependencies =
[ "console"
, "effect"
, "functions"
, "prelude"
, "tuples"
, "typelevel"
, "typelevel-prelude"
]
, repo = "https://github.com/garganscript/purescript-tuples-native"
, version = "v2.3.0"
}
, versions =
{ dependencies = [ "prelude" ]
, repo = "https://github.com/hdgarrood/purescript-versions.git"
, version = "v6.0.0"
}
, web-url =
{ dependencies = [ "prelude" ]
, repo = "https://github.com/mjepronk/purescript-web-url"
, version = "v2.0.0"
}
}
in upstream // overrides // additions
{-
Welcome to a Spago project!
You can edit this file as you like.
Need help? See the following resources:
- Spago documentation: https://github.com/purescript/spago
- Dhall language tour: https://docs.dhall-lang.org/tutorials/Language-Tour.html
When creating a new Spago project, you can use
`spago init --no-comments` or `spago init -C`
to generate this file without the comments in this block.
-}
{ name = "gargantext"
, dependencies =
[ "aff"
, "aff-promise"
, "affjax"
, "affjax-web"
, "argonaut"
, "argonaut-codecs"
, "argonaut-core"
, "arraybuffer-types"
, "arrays"
, "bifunctors"
, "colors"
, "console"
, "control"
, "convertable-options"
, "css"
, "d3"
, "data-default"
, "datetime"
, "debug"
, "dom-filereader"
, "dom-simple"
, "effect"
, "either"
, "enums"
, "exceptions"
, "ffi-simple"
, "foldable-traversable"
, "foreign"
, "foreign-object"
, "form-urlencoded"
, "formatters"
, "functions"
, "graphql-client"
, "heterogeneous"
, "http-methods"
, "integers"
, "js-timers"
, "lists"
, "markdown-it"
, "maybe"
, "media-types"
, "milkis"
, "newtype"
, "nonempty"
, "now"
, "nullable"
, "numbers"
, "ordered-collections"
, "orders"
, "parallel"
, "partial"
, "prelude"
, "profunctor-lenses"
, "psci-support"
, "random"
, "react"
, "reactix"
, "record"
, "record-extra"
, "routing"
, "sequences"
, "simple-json"
, "simple-json-generics"
, "string-search"
, "strings"
, "strings-extra"
, "stringutils"
, "these"
, "toestand"
, "transformers"
, "tuples"
, "tuples-native"
, "typelevel"
, "typelevel-prelude"
, "unfoldable"
, "unordered-collections"
, "unsafe-coerce"
, "uri"
, "uuid"
, "validation"
, "web-file"
, "web-html"
, "web-storage"
, "web-url"
, "web-xhr"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs" ]
}
This diff is collapsed.
workspace:
packageSet:
registry: 50.13.1
extraPackages:
# garganscript packages
d3:
git: https://github.com/garganscript/purescript-d3.git
ref: v0.11.0
debouncing: 0.1.2
reactix: 0.6.1
string-search:
git: https://gitlab.iscpif.fr/gargantext/purescript-string-search.git
ref: spago-next
# custom forks
data-default:
git: https://github.com/garganscript/purescript-data-default.git
ref: v0.4.0
graphql-client:
git: https://github.com/garganscript/purescript-graphql-client.git
ref: spago-next-9.3.2
markdown-it:
git: https://github.com/garganscript/purescript-markdown-it.git
ref: spago-next
sequences:
git: https://github.com/garganscript/purescript-sequences.git
ref: v3.0.2-spago-next
simple-json-generics: 0.2.1
tuples-native:
git: https://github.com/garganscript/purescript-tuples-native.git
ref: v2.3.0-spago-next
# for tests
spec-discovery:
git: https://github.com/garganscript/purescript-spec-discovery.git
ref: v8.2.0-spago-next
package:
name: gargantext
dependencies:
# debugging
- aff: ">=7.1.0 <8.0.0"
- aff-promise: ">=4.0.0 <5.0.0"
- affjax: ">=13.0.0 <14.0.0"
- affjax-web: ">=1.0.0 <2.0.0"
- argonaut: ">=9.0.0 <10.0.0"
- argonaut-codecs: ">=9.1.0 <10.0.0"
- argonaut-core: ">=7.0.0 <8.0.0"
- arraybuffer-types: ">=3.0.2 <4.0.0"
- arrays: ">=7.3.0 <8.0.0"
- bifunctors: ">=6.0.0 <7.0.0"
- colors: ">=7.0.1 <8.0.0"
- console: ">=6.1.0 <7.0.0"
- control: ">=6.0.0 <7.0.0"
- convertable-options: ">=1.0.0 <2.0.0"
- css: ">=6.0.0 <7.0.0"
- d3: "*"
- data-default: "*"
- 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-simple: ">=0.4.0 <0.5.0"
- effect: ">=4.0.0 <5.0.0"
- either: ">=6.1.0 <7.0.0"
- enums: ">=6.0.1 <7.0.0"
- exceptions: ">=6.0.0 <7.0.0"
- ffi-simple: ">=0.5.1 <0.6.0"
- foldable-traversable: ">=6.0.0 <7.0.0"
- foreign: ">=7.0.0 <8.0.0"
- foreign-object: ">=4.1.0 <5.0.0"
- form-urlencoded: ">=7.0.0 <8.0.0"
- formatters: ">=7.0.0 <8.0.0"
- functions: ">=6.0.0 <7.0.0"
- graphql-client: "*"
- heterogeneous: ">=0.6.0 <0.7.0"
- http-methods: ">=6.0.0 <7.0.0"
- integers: ">=6.0.0 <7.0.0"
- js-timers: ">=6.1.0 <7.0.0"
- lists: ">=7.0.0 <8.0.0"
- markdown-it: "*"
- maybe: ">=6.0.0 <7.0.0"
- media-types: ">=6.0.0 <7.0.0"
- milkis: ">=9.0.0 <10.0.0"
- newtype: ">=5.0.0 <6.0.0"
- nonempty: ">=7.0.0 <8.0.0"
- now: ">=6.0.0 <7.0.0"
- nullable: ">=6.0.0 <7.0.0"
- numbers: ">=9.0.1 <10.0.0"
- ordered-collections: ">=3.2.0 <4.0.0"
- orders: ">=6.0.0 <7.0.0"
- parallel: ">=7.0.0 <8.0.0"
- partial: ">=4.0.0 <5.0.0"
- prelude: ">=6.0.1 <7.0.0"
- profunctor-lenses: ">=8.0.0 <9.0.0"
- random: ">=6.0.0 <7.0.0"
- react: ">=11.0.0 <12.0.0"
- reactix: ">=0.6.1 <0.7.0"
- record: ">=4.0.0 <5.0.0"
- record-extra: ">=5.0.1 <6.0.0"
- routing: ">=11.0.0 <12.0.0"
- sequences: "*"
- simple-json: ">=9.0.0 <10.0.0"
- simple-json-generics: "*"
- string-search: "*"
- strings: ">=6.0.1 <7.0.0"
- strings-extra: ">=4.0.0 <5.0.0"
- stringutils: ">=0.0.12 <0.0.13"
- these: ">=6.0.0 <7.0.0"
- toestand: ">=0.9.0 <0.10.0"
- transformers: ">=6.0.0 <7.0.0"
- tuples: ">=7.0.0 <8.0.0"
- tuples-native: "*"
- typelevel: ">=6.0.0 <7.0.0"
- typelevel-prelude: ">=7.0.0 <8.0.0"
- unfoldable: ">=6.0.0 <7.0.0"
- unordered-collections: ">=3.1.0 <4.0.0"
- unsafe-coerce: ">=6.0.0 <7.0.0"
- uri: ">=9.0.0 <10.0.0"
- uuid: ">=9.0.0 <10.0.0"
- validation: ">=6.0.0 <7.0.0"
- web-file: ">=4.0.0 <5.0.0"
- web-html: ">=4.1.0 <5.0.0"
- web-storage: ">=5.0.0 <6.0.0"
- web-url: ">=2.0.0 <3.0.0"
- web-xhr: ">=5.0.1 <6.0.0"
build:
# Be strict about missing packages
# https://github.com/purescript/spago/issues/1211#issuecomment-2066083651
pedanticPackages: true
# convert compiler warnings to errors:
# strict:
# true
censorProjectWarnings:
- UnusedDctorExplicitImport
- UnusedDctorImport
- UnusedDeclaration
- UnusedExplicitImport
- UnusedImport
- UnusedName
- UnusedTypeVar
test:
main: Test.Main
dependencies:
- spec
- spec-discovery
- spec-quickcheck
......@@ -140,6 +140,12 @@ component = R.memo' $ R.hooksComponent componentName cpt where
then showModal window selector modalEvents
else hideModal window selector
-- | When box is true, show the modal immediately
R.useEffectOnce' $ do
if isVisible
then showModal window selector modalEvents
else hideModal window selector
-- | Behaviors
-- |
let
......
......@@ -16,12 +16,14 @@ import Gargantext.Hooks.Session (useSession)
import Gargantext.Routes as GR
import Gargantext.Sessions (sessionId)
import Gargantext.Types (ID, defaultCacheParams)
import Gargantext.Types as GT
import Gargantext.Utils (setter, (?))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
type Props =
( nodeId :: ID
, nodeData :: Node
......@@ -34,7 +36,7 @@ layout :: R2.Leaf Props
layout = R2.leaf layoutCpt
layoutCpt :: R.Component Props
layoutCpt = here.component "layout" cpt where
cpt { nodeId, nodeData: { name } } _ = do
cpt { nodeId, nodeData: { name, node_type } } _ = do
-- | Hooks
-- |
boxes@{
......@@ -69,24 +71,37 @@ layoutCpt = here.component "layout" cpt where
pure $
H.div
{ className: "corpus-layout" }
{ className: "node-layout corpus-layout" }
[
-- FV.backButtonSmart { nodeId, session } []
H.div
{ className: "corpus-layout__title" }
{ className: "node-layout__title corpus-layout__title" }
[
B.div'
{ className: "corpus-layout__title__text" }
name
H.div
{ className: "node-layout__title__content text-primary" }
[
B.icon
{ className: "node-layout__title__icon"
, name: GT.getIcon node_type true
}
,
H.span
{ className: "node-layout__title__text mx-1" }
[ H.text name ]
]
,
-- B.div'
-- { className: "corpus-layout__title__text" }
-- name
-- ,
H.hr
{ className: "corpus-layout__title__line"}
{ className: "node-layout__title__line corpus-layout__title__line"}
,
B.iconButton
{ name: expandTableEdition' ?
"caret-up" $
"caret-down"
, className: "corpos-layout__title__expand"
, className: "node-layout__title__expand corpus-layout__title__expand"
, callback: onExpandClick
}
]
......@@ -94,14 +109,14 @@ layoutCpt = here.component "layout" cpt where
R2.when expandTableEdition' $
H.div
{ className: "corpus-layout__edition-block" }
{ className: "node-layout__edition-block corpus-layout__edition-block" }
[
editionBlock
{ nodeId }
]
,
H.div
{ className: "corpus-layout__code-section" }
{ className: "node-layout__code-section corpus-layout__code-section" }
[
tileMenu
{ boxes
......@@ -129,7 +144,7 @@ layoutCpt = here.component "layout" cpt where
]
,
H.div
{ className: "corpus-layout__folders" }
{ className: "node-layout__folders corpus-layout__folders" }
[
FV.folderView
{ nodeId
......
......@@ -88,6 +88,7 @@ componentCpt = here.component "breadcrumb" cpt where
breadcrumbView { format: "default"
, route: route'
, session: session''
, openTreeNodes: true
}
]
-- ,
......@@ -141,9 +142,10 @@ componentCpt = here.component "breadcrumb" cpt where
]
type BreadcrumbViewProps =
( format :: String
, route :: AppRoute
, session :: Session
( format :: String
, route :: AppRoute
, session :: Session
, openTreeNodes :: Boolean
)
......@@ -151,7 +153,7 @@ breadcrumbView :: R2.Leaf BreadcrumbViewProps
breadcrumbView = R2.leaf breadcrumbViewCpt
breadcrumbViewCpt :: R.Component BreadcrumbViewProps
breadcrumbViewCpt = R2.hereComponent here "breadcrumbViewCpt" hCpt where
hCpt hp { format, route, session } _ = do
hCpt hp { format, route, session, openTreeNodes } _ = do
useLoader { errorHandler: Nothing
, herePrefix: hp
......@@ -163,6 +165,7 @@ breadcrumbViewCpt = R2.hereComponent here "breadcrumbViewCpt" hCpt where
, items
, session
-- , reload: reload
, openTreeNodes
} []
}
......@@ -171,16 +174,17 @@ type BreadcrumbViewMainProps =
, items :: BreadcrumbInfo
, session :: Session
-- , reload :: T.Box T2.Reload
, openTreeNodes :: Boolean
)
breadcrumbViewMain :: R2.Component BreadcrumbViewMainProps
breadcrumbViewMain = R.createElement breadcrumbViewMainCpt
breadcrumbViewMainCpt :: R.Component BreadcrumbViewMainProps
breadcrumbViewMainCpt = here.component "breadcrumbViewMainCpt" cpt where
cpt { items: { parents }, session, format } _ = do
cpt { items: { parents }, session, format, openTreeNodes } _ = do
-- session' <- T.useLive T.unequal session
let items = makeBreadcrumbElements parents session format
let items = makeBreadcrumbElements parents session format openTreeNodes
-- case session of
-- Nothing -> pure $ H.div {} []
......@@ -190,8 +194,8 @@ breadcrumbViewMainCpt = here.component "breadcrumbViewMainCpt" cpt where
R.fragment items
makeBreadcrumbElements :: Array TreeNode -> Session -> String -> Array R.Element
makeBreadcrumbElements items' session format = makeBreadcrumbElementsMap <$> items' where
makeBreadcrumbElements :: Array TreeNode -> Session -> String -> Boolean -> Array R.Element
makeBreadcrumbElements items' session format openTreeNodes = makeBreadcrumbElementsMap <$> items' where
makeBreadcrumbElementsMap :: TreeNode -> R.Element
makeBreadcrumbElementsMap node = breadcrumbItem { linkId: node.id
, linkNodeType: node.node_type
......@@ -201,6 +205,7 @@ breadcrumbViewMainCpt = here.component "breadcrumbViewMainCpt" cpt where
-- , reload: props.reload
-- , style: FolderUp
, format: format
, openTreeNodes: openTreeNodes
}
type BreadcrumbItemProps =
......@@ -212,6 +217,7 @@ type BreadcrumbItemProps =
-- , style :: FolderStyle
, text :: String
, format :: String
, openTreeNodes :: Boolean
)
breadcrumbItem :: R2.Leaf BreadcrumbItemProps
......@@ -226,15 +232,21 @@ breadcrumbItemCpt = here.component "breadcrumbItemCpt" cpt where
-- , reload
-- , style
, format
, openTreeNodes
} _ = do
boxes@{ forestOpen } <- Store.use
boxes@{ route } <- Store.use
let sid = sessionId session
let rootId = treeId session
let currentNodeIdFromUrl = mkNodeId session linkId
R.unsafeHooksEffect $ T.modify_ (openNodesInsert (currentNodeIdFromUrl)) forestOpen
if openTreeNodes then
R.unsafeHooksEffect $ T.modify_ (openNodesInsert (currentNodeIdFromUrl)) forestOpen
else
pure unit
pure $
......
......@@ -90,9 +90,13 @@ type NSCommon =
, handed :: Handed
, session :: Session )
-- The annoying 'render' here is busting a cycle in the low tech
-- way. This function is only called by functions in this module, so
-- we just have to careful in what we pass.
-- | The annoying 'render' here is busting a cycle in the low tech
-- way. This function is only called by functions in this module, so
-- we just have to careful in what we pass.
-- Without the 'render' function though, we get a 'tree' cpt that
-- depends on a 'renderTreeChildren' component, which itself depends
-- on 'tree'. This results in PS 'CycleInDeclaration' compilation
-- error.
type ChildLoaderProps =
( id :: ID
, render :: R2.Leaf TreeProps
......@@ -109,7 +113,6 @@ type PerformActionProps =
-- | Loads and renders the tree starting at the given root node id.
treeLoader :: R2.Leaf ( key :: String | LoaderProps )
treeLoader = R2.leaf treeLoaderCpt
treeLoaderCpt :: R.Component ( key :: String | LoaderProps )
treeLoaderCpt = R2.hereComponent here "treeLoader" hCpt where
-- treeLoaderCpt :: R.Memo LoaderProps
......@@ -155,7 +158,6 @@ getNodeTreeFirstLevel session nodeId = get session $ GR.TreeFirstLevel (Just nod
tree :: R2.Leaf TreeProps
tree props = R.createElement treeCpt props []
treeCpt :: R.Component TreeProps
treeCpt = here.component "tree" cpt where
cpt p@{ frontends
......@@ -255,8 +257,42 @@ renderTreeChildrenCpt = here.component "renderTreeChildren" cpt where
where
nodeProps = RecordE.pick p :: Record NodeProps
renderChild (NTree (LNode {id: cId}) _) = childLoader props [] where
props = Record.merge nodeProps { id: cId, render, root }
-- | | If a child doesn't have children, avoid normal
-- | 'childLoader' which queries API for first-level data (there
-- | is nothing new here) and render the child immediately.
renderChild tree'@(NTree (LNode {id: cId}) []) = childDummyLoader renderProps []
where
renderProps = Record.merge nodeProps { id: cId, render, root, tree: tree' } :: Record ChildDummyLoaderProps
renderChild (NTree (LNode {id: cId}) _children) = childLoader renderProps []
where
renderProps = Record.merge nodeProps { id: cId, render, root } :: Record ChildLoaderProps
type ChildDummyLoaderProps =
( tree :: FTree
| ChildLoaderProps
)
-- | A "dummy" loader: this is because for nodes without children, we
-- | don't want to make the API call.
childDummyLoader :: R2.Component ChildDummyLoaderProps
childDummyLoader = R.createElement childDummyLoaderCpt
childDummyLoaderCpt :: R.Component ChildDummyLoaderProps
childDummyLoaderCpt = R2.hereComponent here "childDummyLoader" hCpt where
hCpt hp p@{ reloadTree
, render
, root
, tree: tree' } _ = do
{ reloadRoot } <- Store.use
reload <- T.useBox T2.newReload
pure $ paint reload tree'
where
paint reload tree' = render (Record.merge base extra) where
base = nodeProps { reload = reload }
extra = { root, tree: tree' }
nodeProps = RecordE.pick p :: Record NodeProps
childLoader :: R2.Component ChildLoaderProps
......
......@@ -31,6 +31,7 @@ import Gargantext.Components.Nodes.Corpus.Types (CorpusData)
import Gargantext.Context.Progress (asyncContext, asyncProgress)
import Gargantext.Ends (Frontends, url)
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Hooks.UpdateEffect (useUpdateEffect1')
import Gargantext.Hooks.Version (Version, useVersion)
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId)
......@@ -100,6 +101,19 @@ nodeSpanCpt = here.component "nodeSpan" cpt
folderOpen' <- R2.useLive' folderOpen
isBoxVisible' <- R2.useLive' isBoxVisible
isBoxVisiblePersist <- T.useBox isBoxVisible'
isBoxVisiblePersist' <- R2.useLive' isBoxVisiblePersist
-- | Modal not visible initially, but visible after first user
-- | click. This is to avoid modal loading initially
-- | (optimization for large trees), but persist it after user
-- | opens it.
useUpdateEffect1' isBoxVisible'
if isBoxVisible'
then T.write_ true isBoxVisiblePersist
else pure unit
-- tasks' <- T.read tasks
-- Computed
......@@ -200,6 +214,22 @@ nodeSpanCpt = here.component "nodeSpan" cpt
host <- R2.getPortalHost
-- Tooltip
let hasTooltip = nodeType == GT.NodeUser
tooltipEl = if hasTooltip then
nodeTooltip
{ id
, nodeType
, name
}
[
case mVersion of
Nothing -> mempty
Just v -> versionComparator v
]
else
H.div {} []
-- Render
pure $
......@@ -221,16 +251,8 @@ nodeSpanCpt = here.component "nodeSpan" cpt
-- // Abstract informations //
nodeTooltip
{ id
, nodeType
, name
}
[
case mVersion of
Nothing -> mempty
Just v -> versionComparator v
]
tooltipEl
,
R.createPortal
[
......@@ -340,24 +362,25 @@ nodeSpanCpt = here.component "nodeSpan" cpt
-- // Modals //
B.baseModal
{ isVisibleBox: isBoxVisible
, noBody: true
, noHeader: true
, modalClassName: "forest-tree-node-modal"
}
[
nodePopupView
{ boxes
, closeCallback: \_ -> T.write_ false isBoxVisible
, dispatch
, id
, name
, nodeType
, session
R2.when isBoxVisiblePersist' (
B.baseModal
{ isVisibleBox: isBoxVisible
, noBody: true
, noHeader: true
, modalClassName: "forest-tree-node-modal"
}
]
]
[
nodePopupView
{ boxes
, closeCallback: \_ -> T.write_ false isBoxVisible
, dispatch
, id
, name
, nodeType
, session
}
]
)
,
-- // Mainleaf indicator of selected node //
--
......@@ -372,6 +395,7 @@ nodeSpanCpt = here.component "nodeSpan" cpt
{ className: "mainleaf-selection-indicator" }
[]
]
]
---------------------------------------------------------
......@@ -595,7 +619,7 @@ nodeActionsCpt = here.component "nodeActions" cpt where
childProps = Record.delete nodeActionsP props
child GT.NodeList = listNodeActions childProps
child GT.Graph = graphNodeActions childProps
-- child GT.Graph = graphNodeActions childProps --Remove the refresh/sync icon removed on #644 (purescript-gargantext)
child _ = mempty
graphNodeActions :: R2.Leaf NodeActionsCommon
......
......@@ -34,6 +34,7 @@ actionDownloadCpt = here.component "actionDownload" cpt where
cpt props@{ nodeType: GT.Graph } _ = pure $ actionDownloadGraph props []
cpt props@{ nodeType: GT.NodeList } _ = pure $ actionDownloadNodeList props []
cpt props@{ nodeType: GT.NodeTexts } _ = pure $ actionDownloadNodeTexts props []
cpt props@{ nodeType: GT.Phylo } _ = pure $ actionDownloadPhylo props []
cpt props@{ nodeType: _ } _ = pure $ actionDownloadOther props []
actionDownloadCorpus :: R2.Component ActionDownload
......@@ -156,6 +157,51 @@ actionDownloadNodeTextsCpt = here.component "actionDownloadNodeTexts" cpt where
info :: NodeTextsDownloadFormat -> String
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
actionDownload GT.Texts id session = pure $ panel [H.div {} [H.text info]]
......
......@@ -156,7 +156,6 @@ settingsBoxLens Corpus =
, Calc
, NodeTexts
, NodeList
, Graph
-- , Dashboard
, Phylo
-- , NodeFrameNotebook
......@@ -288,6 +287,7 @@ settingsBoxLens Notes =
]
settingsBoxLens Phylo =
_buttons .~ [ Reconstruct
, Download
, ShareURL
, Delete
]
......
......@@ -235,6 +235,8 @@ graphViewCpt = R.memo' $ here.component "graphView" cpt where
, sigmaRef
} _ = do
-- { edgeConfluence, edgeWeight } <- GraphStore.use
-- edgeConfluence' <- R2.useLive' edgeConfluence
-- edgeWeight' <- R2.useLive' edgeWeight
-- nodeSize' <- R2.useLive' nodeSize
......@@ -410,7 +412,11 @@ hooksTransformGraph = do
params <- transformGraphStoreParams
graph' <- R2.useLive' store.graph
-- R.useEffect' $ do
-- here.log2 "[hooksTransformGraph] hashed" $ hashLiveProps params
R.useEffect2' (hashLiveProps params) graph' $ do
-- here.log2 "[hooksTransformGraph] transformed" $ transformGraph graph' params
T.write_ (transformGraph graph' params) store.transformedGraph
transformGraph :: SigmaxT.SGraph -> Record LiveProps -> SigmaxT.SGraph
......@@ -450,8 +456,8 @@ transformGraph graph { edgeConfluence'
edge { hidden = true }
edgeHideWeight :: Record SigmaxT.Edge -> Record SigmaxT.Edge
edgeHideWeight edge@{ weightIdx } =
if Range.within edgeWeight' $ toNumber weightIdx then
edgeHideWeight edge@{ weight } =
if Range.within edgeWeight' weight then
edge
else
edge { hidden = true }
......
......@@ -44,6 +44,7 @@ type Store =
, edgeConfluence :: T.Box Range.NumberRange
, edgeConfluenceRange :: T.Box Range.NumberRange
, edgeWeight :: T.Box Range.NumberRange
, edgeWeightRange :: T.Box Range.NumberRange
, forceAtlasState :: T.Box SigmaxT.ForceAtlasState
, noverlapState :: T.Box SigmaxT.NoverlapState
, graphStage :: T.Box GET.Stage
......@@ -79,6 +80,7 @@ type State =
, edgeConfluence :: Range.NumberRange
, edgeConfluenceRange :: Range.NumberRange
, edgeWeight :: Range.NumberRange
, edgeWeightRange :: Range.NumberRange
, forceAtlasState :: SigmaxT.ForceAtlasState
, noverlapState :: SigmaxT.NoverlapState
, graphStage :: GET.Stage
......@@ -109,6 +111,7 @@ options ::
, mouseSelectorSize :: Number
, multiSelectEnabled :: Boolean
, edgeConfluence :: Range.NumberRange
, edgeWeight :: Range.NumberRange
, graphStage :: GET.Stage
, nodeSize :: Range.NumberRange
--, showLouvain :: Boolean
......@@ -131,6 +134,7 @@ options =
, labelRenderedSizeThreshold : 2.0
, mouseSelectorSize : 15.0
, edgeConfluence : Range.Closed { min: 0.0, max: 1.0 }
, edgeWeight : Range.Closed { min: 0.0, max: 1.0 }
, graphStage : GET.Init
, nodeSize : Range.Closed { min: 0.0, max: 100.0 }
--, showLouvain : false
......
......@@ -11,7 +11,7 @@ import Effect.Timer (setTimeout)
import Gargantext.Components.Bootstrap as B
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.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.Types as GET
import Gargantext.Hooks.Sigmax.ForceAtlas2 as ForceAtlas
......@@ -52,7 +52,8 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
-- |
{ edgeConfluence
, edgeConfluenceRange
-- , edgeWeight
, edgeWeight
, edgeWeightRange
, forceAtlasState
, noverlapState
, graph
......@@ -80,6 +81,7 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
selectedNodeIds' <- R2.useLive' selectedNodeIds
showSidebar' <- R2.useLive' showSidebar
edgeConfluenceRange' <- R2.useLive' edgeConfluenceRange
edgeWeightRange' <- R2.useLive' edgeWeightRange
nodeSizeRange' <- R2.useLive' nodeSizeRange
-- session <- useSession
......@@ -207,12 +209,10 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
}
,
gap, gap
,
labelRenderedSizeThresholdButton
{ forceAtlasState
, sigmaRef
, state: labelRenderedSizeThreshold
}
, edgeWeightControl
{ forceAtlasState
, range: edgeWeightRange'
, state: edgeWeight }
]
,
-- Run spatialization
......@@ -321,12 +321,12 @@ controlsCpt = R.memo' $ here.component "controls" cpt where
{ forceAtlasState
, range: edgeConfluenceRange'
, state: edgeConfluence }
{- ,
edgeWeightControl
{ forceAtlasState
, range: edgeWeightRange
, state: edgeWeight }
-}
, gap
, labelRenderedSizeThresholdButton
{ forceAtlasState
, sigmaRef
, state: labelRenderedSizeThreshold
}
,
gap, gap
,
......
......@@ -6,19 +6,29 @@ module Gargantext.Components.GraphExplorer.Toolbar.RangeControl
, nodeSizeControl
) 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 Reactix as R
import Reactix.DOM.HTML as H
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 "Gargantext.Components.GraphExplorer.Toolbar.RangeControl"
defaultThrottleInterval :: Int
defaultThrottleInterval = 500
type Props =
( caption :: String
, sliderProps :: Record RS.Props
......@@ -54,22 +64,24 @@ edgeConfluenceControlCpt :: R.Component EdgeConfluenceControlProps
edgeConfluenceControlCpt = here.component "edgeConfluenceControl" cpt
where
cpt { forceAtlasState
, range: Range.Closed { min, max }
, range
, state
} _ = do
forceAtlasState' <- R2.useLive' forceAtlasState
state' <- T.useLive T.unequal state
pure $ rangeControl {
caption: "Edge Confluence Weight"
caption: "Edge Confluence Weight"
, sliderProps: {
bounds: Range.Closed { min, max }
bounds: range
, epsilon: 0.01
, height: 5.0
, initialValue: state'
, onChange: \rng -> T.write_ rng state
, status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
, step: 1.0
, throttleInterval: Just defaultThrottleInterval
, width: 10.0
}
}
......@@ -88,22 +100,27 @@ edgeWeightControlCpt :: R.Component EdgeWeightControlProps
edgeWeightControlCpt = here.component "edgeWeightControl" cpt
where
cpt { forceAtlasState
, range: Range.Closed { min, max }
, range: range@(Range.Closed { min, max })
, state
} _ = do
forceAtlasState' <- R2.useLive' forceAtlasState
state' <- T.useLive T.unequal state
pure $ rangeControl {
caption: "Edge Weight"
caption: "Edge Weight"
, sliderProps: {
bounds: Range.Closed { min, max }
bounds: range
, initialValue: state'
, epsilon: 1.0
, epsilon: (max - min) / 100.0
, height: 5.0
, onChange: \rng -> T.write_ rng state
-- , onChange: \rng -> Debounce.call onChange rng
-- , onChange: \rng -> RD.callDebouncedCallback rd rng
-- , onChange: onChange'
, status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
, step: 1.0
, throttleInterval: Just defaultThrottleInterval
, width: 10.0
}
}
......@@ -138,6 +155,7 @@ nodeSizeControlCpt = here.component "nodeSizeControl" cpt
, onChange: \rng -> T.write_ rng state
, status: SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
, step: 1.0
, throttleInterval: Just defaultThrottleInterval
, width: 10.0
}
}
......@@ -7,10 +7,11 @@ module Gargantext.Components.GraphExplorer.Toolbar.SlideButton
) where
import Data.Map as Map
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Number as DN
import Prelude
import Effect (Effect)
import Effect.Debouncing as Debounce
import Prelude
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
......@@ -25,20 +26,29 @@ import Gargantext.Utils.Reactix as R2
here :: R2.Here
here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.SlideButton"
defaultThrottleInterval :: Int
defaultThrottleInterval = 500
type Props =
( caption :: String
, forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
, min :: Number
, max :: Number
, onChange :: forall e. e -> Effect Unit
, state :: T.Box Number
( caption :: String
, forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
, min :: Number
, max :: Number
, onChange :: Number -> Effect Unit
, state :: T.Box Number
, throttleInterval :: Maybe Int -- then Nothing, no throttling is done
)
sizeButton :: Record Props -> R.Element
sizeButton props = R.createElement sizeButtonCpt props []
sizeButtonCpt :: R.Component Props
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
forceAtlasState' <- R2.useLive' forceAtlasState
......@@ -61,7 +71,11 @@ sizeButtonCpt = here.component "sizeButton" cpt where
, min: show min
, max: show max
, 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"
, disabled: status == Disabled
}
......@@ -92,30 +106,27 @@ labelSizeButtonCpt = here.component "labelSizeButton" cpt
, forceAtlasState
, min: minLabelSize
, max: maxLabelSize
, onChange: \e -> do
, onChange: \newValue -> do
let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e
case newValue' of
Nothing -> pure unit
Just newValue ->
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
let ratio = (newValue - minLabelSize) / (defaultLabelSize - minLabelSize)
let nodes = SigmaxTypes.graphNodes graph'
let nodesResized = (\n@{ size } -> n { size = size * ratio }) <$> nodes
let nodesMap = SigmaxTypes.idMap nodesResized
Graphology.forEachNode (Sigma.graph s) $ \{ id } -> do
case Map.lookup id nodesMap of
Nothing -> pure unit
Just { size } -> Graphology.mergeNodeAttributes (Sigma.graph s) id { size }
Sigma.setSettings s {
defaultLabelSize: newValue
, drawLabels: true
, labelSize: newValue
-- , maxNodeSize: newValue / 2.5
--, labelSizeRatio: newValue / 2.5
}
T.write_ newValue state
Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
let ratio = (newValue - minLabelSize) / (defaultLabelSize - minLabelSize)
let nodes = SigmaxTypes.graphNodes graph'
let nodesResized = (\n@{ size } -> n { size = size * ratio }) <$> nodes
let nodesMap = SigmaxTypes.idMap nodesResized
Graphology.forEachNode (Sigma.graph s) $ \{ id } -> do
case Map.lookup id nodesMap of
Nothing -> pure unit
Just { size } -> Graphology.mergeNodeAttributes (Sigma.graph s) id { size }
Sigma.setSettings s {
defaultLabelSize: newValue
, drawLabels: true
, labelSize: newValue
-- , maxNodeSize: newValue / 2.5
--, labelSizeRatio: newValue / 2.5
}
T.write_ newValue state
, throttleInterval: Just defaultThrottleInterval
}
type LabelRenderedSizeThresholdButtonProps =
......@@ -135,17 +146,14 @@ labelRenderedSizeThresholdButtonCpt = here.component "labelRenderedSizeThreshold
, forceAtlasState
, min: 0.0
, max: 10.0
, onChange: \e -> do
, onChange: \newValue -> do
let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e
case newValue' of
Nothing -> pure unit
Just newValue ->
Sigmax.dependOnSigma sigma "[labelRenderdSizeThresholdButton] sigma: Nothing" $ \s -> do
Sigma.setSettings s {
labelRenderedSizeThreshold: newValue
}
T.write_ newValue state
Sigmax.dependOnSigma sigma "[labelRenderdSizeThresholdButton] sigma: Nothing" $ \s -> do
Sigma.setSettings s {
labelRenderedSizeThreshold: newValue
}
T.write_ newValue state
, throttleInterval: Just defaultThrottleInterval
}
type MouseSelectorSizeSliderProps =
......@@ -164,16 +172,13 @@ mouseSelectorSizeSliderCpt = here.component "mouseSelectorSizeSlider" cpt
, forceAtlasState
, min: 1.0
, max: 100.0
, onChange: \e -> do
, onChange: \newValue -> do
let sigma = R.readRef sigmaRef
let newValue' = DN.fromString $ R.unsafeEventValue e
case newValue' of
Nothing -> pure unit
Just newValue ->
Sigmax.dependOnSigma sigma "[mouseSelectorSizeButton] sigma: Nothing" $ \s -> do
Sigma.setSettings s {
mouseSelectorSize: newValue
}
T.write_ newValue state
Sigmax.dependOnSigma sigma "[mouseSelectorSizeButton] sigma: Nothing" $ \s -> do
Sigma.setSettings s {
mouseSelectorSize: newValue
}
T.write_ newValue state
, state
, throttleInterval: Just defaultThrottleInterval
}
......@@ -25,7 +25,6 @@ import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session(..))
import Gargantext.Types (NodeType)
import Gargantext.Utils.Reactix as R2
import GraphQL.Client.Args (type (==>))
import GraphQL.Client.BaseClients.Urql (UrqlClient, createClient)
import GraphQL.Client.Query (decodeGqlRes) --, mutationJson)
import GraphQL.Client.SafeQueryName (safeQueryName)
......@@ -146,27 +145,27 @@ mutationGql session name q = do
-- Schema
type Schema
= { annuaire_contacts :: { contact_id :: Int } ==> Array AnnuaireContact
, context_ngrams :: { context_id :: Int, list_id :: Int } ==> Array String
, contexts :: { context_id :: Int, node_id :: Int } ==> Array GQLCTX.NodeContext
, contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String } ==> Array GQLCTX.Context
, imt_schools :: {} ==> Array GQLIMT.School
, languages :: {} ==> Array GQLNLP.Language
, node_children :: { node_id :: Int, child_type :: NodeType } ==> Array GQLNode.Node
, node_parent :: { node_id :: Int, parent_type :: NodeType } ==> Array GQLNode.Node
, nodes :: { node_id :: Int } ==> Array GQLNode.Node
, nodes_corpus :: { corpus_id :: Int } ==> Array GQLNode.Corpus
, user_infos :: { user_id :: Int } ==> Array UserInfo
, users :: { user_id :: Int } ==> Array User
, team :: { team_node_id :: Int } ==> Team
, tree :: { root_id :: Int } ==> TreeFirstLevel
, tree_branch :: { node_id :: Int } ==> BreadcrumbInfo
= { annuaire_contacts :: { contact_id :: Int } -> Array AnnuaireContact
, context_ngrams :: { context_id :: Int, list_id :: Int } -> Array String
, contexts :: { context_id :: Int, node_id :: Int } -> Array GQLCTX.NodeContext
, contexts_for_ngrams :: { corpus_id :: Int, ngrams_terms :: Array String } -> Array GQLCTX.Context
, imt_schools :: {} -> Array GQLIMT.School
, languages :: {} -> Array GQLNLP.Language
, node_children :: { node_id :: Int, child_type :: NodeType } -> Array GQLNode.Node
, node_parent :: { node_id :: Int, parent_type :: NodeType } -> Array GQLNode.Node
, nodes :: { node_id :: Int } -> Array GQLNode.Node
, nodes_corpus :: { corpus_id :: Int } -> Array GQLNode.Corpus
, user_infos :: { user_id :: Int } -> Array UserInfo
, users :: { user_id :: Int } -> Array User
, team :: { team_node_id :: Int } -> Team
, tree :: { root_id :: Int } -> TreeFirstLevel
, tree_branch :: { node_id :: Int } -> BreadcrumbInfo
}
type Mutation
= { update_user_info :: UserInfoM ==> Int
, update_user_pubmed_api_key :: UserPubmedAPIKeyM ==> Int
, update_user_epo_api_user :: UserEPOAPIUserM ==> Int
, update_user_epo_api_token :: UserEPOAPITokenM ==> Int
, delete_team_membership :: TeamDeleteM ==> Array Int
, update_node_context_category :: GQLCTX.NodeContextCategoryM ==> Array Int }
= { update_user_info :: UserInfoM -> Int
, update_user_pubmed_api_key :: UserPubmedAPIKeyM -> Int
, update_user_epo_api_user :: UserEPOAPIUserM -> Int
, update_user_epo_api_token :: UserEPOAPITokenM -> Int
, delete_team_membership :: TeamDeleteM -> Array Int
, update_node_context_category :: GQLCTX.NodeContextCategoryM -> Array Int }
......@@ -44,7 +44,7 @@ getNode session nodeId = do
case eRes of
Left err -> pure $ Left err
Right { nodes } -> do
liftEffect $ here.log2 "[getNode] node" nodes
-- liftEffect $ here.log2 "[getNode] node" nodes
pure $ case A.head nodes of
Nothing -> Left (CustomError $ "node with id" <> show nodeId <>" not found")
Just node -> Right node
......@@ -145,7 +145,7 @@ getTreeFirstLevel session id = do
case eRes of
Left err -> pure $ Left err
Right { tree } -> do
liftEffect $ here.log2 "[getTreeFirstLevel] tree first level" tree
-- liftEffect $ here.log2 "[getTreeFirstLevel] tree first level" tree
pure $ Right tree -- TODO: error handling
getTeam :: Session -> Int -> AffRESTError Team
......
module Gargantext.Components.GraphQL.Node where
import Gargantext.Prelude
import Gargantext.Types (NodeType)
import Gargantext.Utils.GraphQL as GGQL
import Gargantext.Types (NodeType)
import GraphQL.Client.Args (Args, (=>>))
......@@ -12,13 +13,15 @@ type Corpus
= { id :: Int
, name :: String
, parent_id :: Int
, type_id :: Int }
, type_id :: Int
, node_type :: NodeType }
type Node
= { id :: Int
, name :: String
, parent_id :: Int
, type_id :: Int }
, type_id :: Int
, node_type :: NodeType }
type NodesCorpusQuery =
{ nodes_corpus :: Args
......@@ -26,7 +29,8 @@ type NodesCorpusQuery =
{ id :: Unit
, name :: Unit
, parent_id :: Unit
, type_id :: Unit } }
, type_id :: Unit
, node_type :: Unit } }
type NodesQuery =
{ nodes :: Args
......@@ -34,7 +38,8 @@ type NodesQuery =
{ id :: Unit
, name :: Unit
, parent_id :: Unit
, type_id :: Unit } }
, type_id :: Unit
, node_type :: Unit } }
nodesQuery :: NodesQuery
nodesQuery = { nodes: { node_id: Var :: _ "id" Int } =>>
......
......@@ -120,7 +120,7 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
onInput :: forall event. T.Box Completions -> event -> Effect Unit
onInput completions e = do
let val = S.trim $ R.unsafeEventValue e
let val = R.unsafeEventValue e
T.write_ val state
cs <- autocompleteSearch val
T.write_ cs completions
......
......@@ -23,6 +23,6 @@ loadingSpinnerCpt = here.component "LoadingSpinner" cpt where
-- cpt _ _ = H.i {className: "fa fa-circle-o-notch fa-spin fa-3x fa-fw"} [H.text ""]
cpt { additionalClass } _ = do
pure $ H.i { className: "fa fa-spinner fa-pulse fa-3x fa-fw " <> c } [H.text ""]
pure $ H.i { className: "fa fa-spinner fa-pulse fa-fw " <> c } [H.text ""]
where
c = fromMaybe "" additionalClass
......@@ -83,7 +83,6 @@ loginCpt = here.component "login" cpt where
-- | @link https://github.com/facebook/react/issues/12247
loginContainer :: R2.Leaf Props
loginContainer = R2.leaf loginContainerCpt
loginContainerCpt :: R.Component Props
loginContainerCpt = here.component "container" cpt where
cpt props@{ sessions, visible, loginRedirect } _ = do
......@@ -360,7 +359,7 @@ renderBackendCpt = here.component "renderBackend" cpt where
{}
[
B.icon
{ name: "database"
{ name: "server"
}
]
,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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