Commit 50f8c197 authored by Alexandre Delanoë's avatar Alexandre Delanoë

[MERGE]

parents e4dcc134 7885a6ba
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2,24 +2,90 @@ module Gargantext.Components.App (app) where
import Gargantext.Prelude
import Data.Tuple.Nested ((/\))
import Gargantext.AsyncTasks as GAT
import Gargantext.Components.App.Store as AppStore
import Gargantext.Components.Router (router)
import Gargantext.Hooks (useHashRouter)
import Gargantext.Hooks.FirstEffect (useFirstEffect')
import Gargantext.Router as Router
import Gargantext.Sessions as Sessions
import Gargantext.Types (CacheParams, defaultCacheParams)
import Gargantext.Utils (getter)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Record as Record
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.App"
app :: R2.Component ()
app = R.createElement appCpt
app :: R2.Leaf ()
app = R2.leaf appCpt
appCpt :: R.Component ()
appCpt = here.component "app" cpt where
appCpt = here.component "container" cpt where
cpt _ _ = do
-- | States
-- |
cache' /\ cache <- R2.useBox' (defaultCacheParams :: CacheParams)
-- | Hooks
-- |
-- load Local Storage cache (if exists)
useFirstEffect' $
R2.loadLocalStorageState R2.appParamsKey cache
-- | Render
-- |
pure $
hydrateStore
{ cacheParams: cache'
}
--------------------------------------------------------------
type HydrateStoreProps =
( cacheParams :: CacheParams
)
hydrateStore :: R2.Leaf HydrateStoreProps
hydrateStore = R2.leaf hydrateStoreCpt
hydrateStoreCpt :: R.Component HydrateStoreProps
hydrateStoreCpt = here.component "hydrateStore" cpt where
cpt { cacheParams
} _ = do
-- | Computed
-- |
(state :: Record AppStore.State) <- pure $
-- (cache options)
{ expandTableEdition: getter _.expandTableEdition cacheParams
-- (default options)
} `Record.merge` AppStore.options
-- | Render
-- |
pure $
AppStore.provide
state
[
mainApp
{}
]
--------------------------------------------------------------
mainApp :: R2.Leaf ()
mainApp = R2.leaf mainAppCpt
mainAppCpt :: R.Component ()
mainAppCpt = here.component "main" cpt where
cpt _ _ = do
boxes <- AppStore.use
-- tasks <- T.useBox Nothing -- storage for asynchronous tasks reductor
......
......@@ -38,6 +38,7 @@ here = R2.here "Gargantext.Components.App.Store"
type Store =
( backend :: T.Box (Maybe Backend)
, errors :: T.Box (Array FrontendError)
, expandTableEdition :: T.Box Boolean
, forestOpen :: T.Box OpenNodes
, graphVersion :: T2.ReloadS
, handed :: T.Box Handed
......@@ -63,6 +64,7 @@ type Store =
type State =
( backend :: Maybe Backend
, errors :: Array FrontendError
, expandTableEdition :: Boolean
, forestOpen :: OpenNodes
, graphVersion :: T2.Reload
, handed :: Handed
......@@ -89,6 +91,7 @@ options :: Record State
options =
{ backend : Nothing
, errors : []
, expandTableEdition : false
, forestOpen : OpenNodes $ Set.empty
, graphVersion : T2.newReload
, handed : RightHanded
......
......@@ -24,6 +24,7 @@ type Options =
, overlay :: Boolean
, elevation :: Elevation
, variant :: Variant
, focusRing :: Boolean
)
options :: Record Options
......@@ -34,6 +35,7 @@ options =
, overlay : true
, elevation : Level0
, variant : Dark
, focusRing : true
}
-- | Structural Component for a simple Glyphicon element with call-to-action
......@@ -67,6 +69,9 @@ component = R.hooksComponent componentName cpt where
componentName <> "--overlay" $
""
, componentName <> "--" <> show props.elevation
, props.focusRing ?
componentName <> "--focus-ring" $
""
]
contentClassName = intercalate " "
......
module Gargantext.Components.CodeEditor where
import Gargantext.Prelude
import DOM.Simple.Types (Element)
import Data.Argonaut.Parser (jsonParser)
import Data.Either (either, Either(..))
import Data.Generic.Rep (class Generic)
import Data.Either (Either(..))
import Data.Eq.Generic (genericEq)
import Data.Show.Generic (genericShow)
import Data.Foldable (intercalate)
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Data.Nullable (Nullable, null, toMaybe)
import Data.Show.Generic (genericShow)
import Data.String.Utils (endsWith)
import DOM.Simple.Types (Element)
import Effect (Effect)
import FFI.Simple ((.=))
import Gargantext.Components.Bootstrap as B
import Gargantext.Utils.HighlightJS as HLJS
import Gargantext.Utils.Reactix as R2
import MarkdownIt (renderString)
import Reactix as R
import Reactix.DOM.HTML as H
-- import Text.Markdown.SlamDown.Parser (parseMd)
-- import Text.Markdown.SlamDown.Smolder as MD
-- import Text.Markdown.SlamDown.Syntax (SlamDownP)
-- import Text.Smolder.Renderer.String as Smolder
import Toestand as T
import Gargantext.Prelude
import Gargantext.Utils.HighlightJS as HLJS
import Gargantext.Utils.Reactix as R2
here :: R2.Here
here = R2.here "Gargantext.Components.CodeEditor"
......@@ -102,41 +100,70 @@ renderPython :: String -> String
renderPython s = s
codeEditor :: Record Props -> R.Element
codeEditor p = R.createElement codeEditorCpt p []
-- | The code editor contains 3 components:
-- | - a hidden textarea
-- | - textarea code overlay
-- | - html preview
-- |
-- | The overlay is to provide seamless syntax highlighting on top of the
-- | textarea.
-- |
-- | I took the idea from: https://github.com/satya164/react-simple-code-editor
codeEditor :: R2.Leaf Props
codeEditor = R2.leaf codeEditorCpt
-- The code editor contains 3 components:
-- - a hidden textarea
-- - textarea code overlay
-- - html preview
-- The overlay is to provide seamless syntax highlighting on top of the textarea.
-- I took the idea from: https://github.com/satya164/react-simple-code-editor
codeEditorCpt :: R.Component Props
codeEditorCpt = here.component "codeEditor" cpt
where
codeEditorCpt = here.component "codeEditor" cpt where
cpt {code, defaultCodeType, onChange} _ = do
-- | States
-- |
controls <- initControls code defaultCodeType
codeS' <- T.useLive T.unequal controls.codeS
codeType' <- T.useLive T.unequal controls.codeType
viewType' <- T.useLive T.unequal controls.viewType
-- | Effects
-- |
R.useEffect2' codeS' codeType' $ do
setCodeOverlay controls.codeOverlayElRef codeType' codeS'
renderHtml codeS' codeType' controls.htmlElRef controls.error
pure $ H.div { className: "code-editor" }
[ toolbar { controls, onChange }
, H.div { className: "row no-gutters error" }
[ errorComponent {error: controls.error} ]
, H.div { className: "row no-gutters editor" }
[ H.div { className: "code-area " <> (codeHidden viewType') }
[ H.div { className: "code-container" }
[ H.textarea { defaultValue: codeS'
-- | Render
-- |
pure $
H.div
{ className: "code-editor" }
[
toolbar
{ controls, onChange }
,
H.div
{ className: "row no-gutters error" }
[
errorComponent
{error: controls.error}
]
,
H.div
{ className: "row no-gutters editor" }
[
H.div
{ className: "code-area " <> (codeHidden viewType') }
[
H.div
{ className: "code-container" }
[
H.textarea
{ defaultValue: codeS'
, on: { change: onEditChange controls.codeS codeType' onChange }
, placeholder: "Type some code..."
, ref: controls.codeElRef } [ ]
, H.pre { className: (langClass codeType')
, ref: controls.codeElRef
} []
,
H.pre
{ className: (langClass codeType')
-- , contentEditable: "true"
, ref: controls.codeOverlayElRef
, rows: 30
......@@ -144,13 +171,19 @@ codeEditorCpt = here.component "codeEditor" cpt
} []
]
]
, H.div { className: "v-divider " <> (dividerHidden viewType') } [ H.text " " ]
, H.div { className: "html " <> (langClass codeType') <> (previewHidden viewType')
,
H.div
{ className: "v-divider " <> (dividerHidden viewType') }
[ H.text " " ]
,
H.div
{ className: "html " <> (langClass codeType') <> (previewHidden viewType')
, ref: controls.htmlElRef
} []
]
]
-- | Helpers
-- |
codeHidden :: ViewType -> String
codeHidden Code = ""
codeHidden Both = ""
......@@ -205,33 +238,52 @@ renderHtml code codeType htmlElRef error =
type OnChangeCodeType = CodeType -> Code -> Effect Unit
type ToolbarProps = (
controls :: Record Controls
type ToolbarProps =
( controls :: Record Controls
, onChange :: OnChangeCodeType
)
toolbar :: Record ToolbarProps -> R.Element
toolbar p = R.createElement toolbarCpt p []
toolbar :: R2.Leaf ToolbarProps
toolbar = R2.leaf toolbarCpt
toolbarCpt :: R.Component ToolbarProps
toolbarCpt = here.component "toolbar" cpt
where
toolbarCpt = here.component "toolbar" cpt where
cpt { controls: { codeS, codeType, viewType }
, onChange } _ = do
, onChange
} _ = do
-- | States
-- |
codeS' <- T.useLive T.unequal codeS
codeType' <- T.useLive T.unequal codeType
-- codeType' <- T.useLive T.unequal codeType
-- | Render
-- |
pure $
H.div { className: "row no-gutters align-items-center mb-3 code-editor__toolbar" }
[ H.div { className: "code-editor__toolbar__type" }
[ codeTypeSelector {
codeType
H.div
{ className: intercalate " "
[ "code-editor__toolbar"
, "row no-gutters align-items-center mb-3"
]
}
[
H.div
{ className: "code-editor__toolbar__type" }
[
codeTypeSelector
{ codeType
-- Handle rerendering of preview when viewType changed
, onChange: \ct -> onChange ct codeS'
}
]
, H.div {}
[ viewTypeSelector {state: viewType} [] ]
,
H.div
{}
[
viewTypeSelector
{ state: viewType
}
]
]
......@@ -255,27 +307,47 @@ errorComponentCpt = here.component "errorComponent" cpt
type CodeTypeSelectorProps =
(
codeType :: T.Box CodeType
( codeType :: T.Box CodeType
, onChange :: CodeType -> Effect Unit
)
codeTypeSelector :: Record CodeTypeSelectorProps -> R.Element
codeTypeSelector p = R.createElement codeTypeSelectorCpt p []
codeTypeSelector :: R2.Leaf CodeTypeSelectorProps
codeTypeSelector = R2.leaf codeTypeSelectorCpt
codeTypeSelectorCpt :: R.Component CodeTypeSelectorProps
codeTypeSelectorCpt = here.component "codeTypeSelector" cpt
where
codeTypeSelectorCpt = here.component "codeTypeSelector" cpt where
cpt { codeType, onChange } _ = do
-- | States
-- |
codeType' <- T.useLive T.unequal codeType
pure $ R2.select { className: "form-control"
-- | Render
-- |
pure $
H.div
{ className: "input-group input-group-sm" }
[
H.div
{ className: "input-group-prepend" }
[
B.icon
{ name: "code"
, className: "input-group-text"
}
]
,
R2.select
{ className: "form-control"
, defaultValue: show codeType'
, on: { change: onSelectChange codeType onChange }
, style: { width: "150px" }
}
(option <$> [JSON, Markdown, Haskell, Python])
]
-- | Helpers
-- |
option :: CodeType -> R.Element
option value = H.option { value: show value } [ H.text $ show value ]
......@@ -294,31 +366,41 @@ codeTypeSelectorCpt = here.component "codeTypeSelector" cpt
type ViewTypeSelectorProps =
(
state :: T.Box ViewType
( state :: T.Box ViewType
)
viewTypeSelector :: R2.Component ViewTypeSelectorProps
viewTypeSelector = R.createElement viewTypeSelectorCpt
viewTypeSelector :: R2.Leaf ViewTypeSelectorProps
viewTypeSelector = R2.leaf viewTypeSelectorCpt
viewTypeSelectorCpt :: R.Component ViewTypeSelectorProps
viewTypeSelectorCpt = here.component "viewTypeSelector" cpt
where
viewTypeSelectorCpt = here.component "viewTypeSelector" cpt where
cpt { state } _ = do
-- | States
-- |
state' <- T.useLive T.unequal state
pure $ H.div { className: "btn-group"
, role: "group" } [
viewTypeButton Code state' state
-- | Render
-- |
pure $
H.div
{ className: "btn-group btn-group-sm"
, role: "group"
}
[ viewTypeButton Code state' state
, viewTypeButton Both state' state
, viewTypeButton Preview state' state
]
-- | Helpers
-- |
viewTypeButton viewType state' state =
H.button { className: "btn btn-primary" <> active
H.button
{ className: "btn btn-light" <> active
, on: { click: \_ -> T.write viewType state }
, type: "button"
} [
}
[
H.i { className: "fa " <> (icon viewType) } []
]
where
......
This diff is collapsed.
module Gargantext.Components.Corpus.EditionBlock
( editionBlock
) where
import Gargantext.Prelude
import Data.Maybe (Maybe(..), isJust)
import Data.Tuple.Nested ((/\))
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Corpus.CodeSection (loadCorpus')
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Nodes.Corpus.Types (CorpusInfo(..), Hyperdata(..), getCorpusInfo)
import Gargantext.Components.Table (tableHeaderEditionBlock)
import Gargantext.Config.REST (logRESTError)
import Gargantext.Hooks.Loader (useLoaderEffect)
import Gargantext.Hooks.Session (useSession)
import Gargantext.Types (ID)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
type Props =
( nodeId :: ID
)
here :: R2.Here
here = R2.here "Gargantext.Components.Corpus.EditionBlock"
editionBlock :: R2.Leaf Props
editionBlock = R2.leaf editionBlockCpt
editionBlockCpt :: R.Component Props
editionBlockCpt = here.component "main" cpt where
cpt { nodeId
} _ = do
-- | States
-- |
session <- useSession
state' /\ state <- R2.useBox' Nothing
-- | Computed
-- |
let
errorHandler = logRESTError here "[corpusLayout]"
-- | Hooks
-- |
useLoaderEffect
{ errorHandler
, loader: loadCorpus'
, path: { nodeId, session }
, state
}
-- | Render
-- |
pure $
B.cloak
{ isDisplayed: isJust state'
, cloakSlot:
-- (?) quick and dirty placeholder for the <tableHeaderEditionBlock>
H.div
{ style:
{ width: "100%"
, height: "136px"
, position: "relative"
}
}
[
B.preloader
{}
]
, defaultSlot:
R2.fromMaybe state' \hyperdata ->
editionBlock_
{ nodeId
, hyperdata
}
}
----------------------------------------------------------------
type Props_ =
( nodeId :: ID
, hyperdata :: NodePoly Hyperdata
)
editionBlock_ :: R2.Leaf Props_
editionBlock_ = R2.leaf editionBlockCpt_
editionBlockCpt_ :: R.Component Props_
editionBlockCpt_ = here.component "main_" cpt where
cpt { nodeId
, hyperdata
} _ = do
-- | Computed
-- |
let
NodePoly { name, date, hyperdata } = hyperdata
Hyperdata h = hyperdata
corpusInfo = getCorpusInfo h.fields
CorpusInfo { title, desc, query, authors } = corpusInfo
-- -- | States
-- -- |
corpusInfoS <- T.useBox corpusInfo
session <- useSession
-- -- | Render
-- -- |
pure $
tableHeaderEditionBlock
{ hyperdata
, nodeId
, session
, corpusInfoS
, defaultData:
{ name
, date
, query
, desc
, title
, authors
}
}
module Gargantext.Components.Corpus.Layout where
import Gargantext.Prelude
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Gargantext.Components.App.Store as AppStore
import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (ButtonVariant(..), ComponentStatus(..), Sizing(..), Variant(..))
import Gargantext.Components.Corpus.EditionBlock (editionBlock)
import Gargantext.Components.FolderView as FV
import Gargantext.Components.GraphQL.Node (Node)
import Gargantext.Components.TileMenu (tileMenu)
import Gargantext.Hooks.FirstEffect (useFirstEffect')
import Gargantext.Hooks.Session (useSession)
import Gargantext.Routes as GR
import Gargantext.Sessions (sessionId)
import Gargantext.Types (ID, defaultCacheParams)
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
)
here :: R2.Here
here = R2.here "Gargantext.Components.Corpus.Layout"
layout :: R2.Leaf Props
layout = R2.leaf layoutCpt
layoutCpt :: R.Component Props
layoutCpt = here.component "layout" cpt where
cpt { nodeId, nodeData: { name } } _ = do
-- | Hooks
-- |
boxes@{
expandTableEdition
} <- AppStore.use
expandTableEdition' <- R2.useLive' expandTableEdition
session <- useSession
-- | Computed
-- |
let
corpusCodeRoute = const do
pure $ GR.CorpusCode (sessionId session) nodeId
-- | Effect
-- |
-- transfer local Component change to Local Storage cache
useFirstEffect' $
flip T.listen expandTableEdition onExpandTableEditionChange
-- | Behaviors
-- |
let
onExpandClick _ = T.modify_ (not) expandTableEdition
-- | Render
-- |
pure $
H.div
{ className: "corpus-layout" }
[
-- FV.backButtonSmart { nodeId, session } []
H.div
{ className: "corpus-layout__title" }
[
B.div'
{ className: "corpus-layout__title__text" }
name
,
H.hr
{ className: "corpus-layout__title__line"}
,
B.iconButton
{ name: expandTableEdition' ?
"caret-up" $
"caret-down"
, className: "corpos-layout__title__expand"
, callback: onExpandClick
}
]
,
R2.when expandTableEdition' $
H.div
{ className: "corpus-layout__edition-block" }
[
editionBlock
{ nodeId }
]
,
H.div
{ className: "corpus-layout__code-section" }
[
tileMenu
{ boxes
, currentTile: Just corpusCodeRoute
, xTile: Just corpusCodeRoute
, yTile: Just corpusCodeRoute
}
[
B.button
{ callback: const $ pure unit
, status: Muted
, size: SmallSize
, variant: ButtonVariant Secondary
}
[
B.icon
{ name: "code" }
,
B.wad_
[ "d-inline-block", "virtual-space", "w-1" ]
,
H.text "Code section"
]
]
]
,
H.div
{ className: "corpus-layout__folders" }
[
FV.folderView
{ nodeId
, session
}
]
]
onExpandTableEditionChange :: T.Change Boolean -> Effect Unit
onExpandTableEditionChange { new } = do
cache <- R2.loadLocalStorageState' R2.appParamsKey defaultCacheParams
let update = setter (_ { expandTableEdition = new }) cache
R2.setLocalStorageState R2.appParamsKey update
This diff is collapsed.
......@@ -23,9 +23,9 @@ import Gargantext.Components.Forest.Tree.Node.Action.Upload.Types (FileType(..),
import Gargantext.Components.Forest.Tree.Node.Box (nodePopupView)
import Gargantext.Components.Forest.Tree.Node.Settings (SettingsBox(..), settingsBox)
import Gargantext.Components.Forest.Tree.Node.Tools.Sync (nodeActionsGraph, nodeActionsNodeList)
import Gargantext.Components.Corpus.CodeSection (loadCorpusWithChild)
import Gargantext.Components.GraphExplorer.API as GraphAPI
import Gargantext.Components.Lang (Lang(EN))
import Gargantext.Components.Nodes.Corpus (loadCorpusWithChild)
import Gargantext.Config.REST (logRESTError)
import Gargantext.Context.Progress (asyncContext, asyncProgress)
import Gargantext.Ends (Frontends, url)
......
......@@ -321,7 +321,7 @@ contactFormCpt = here.component "form" cpt where
]
,
B.wad
[ "align-self-start", "ml-3" ]
[ "align-self-flex-start", "ml-3" ]
[
B.caveat
{}
......
This diff is collapsed.
......@@ -9,7 +9,7 @@ import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Class (liftEffect)
import Gargantext.Components.App.Store (Boxes)
import Gargantext.Components.Nodes.Corpus (fieldsCodeEditor)
import Gargantext.Components.Corpus.CodeSection (fieldsCodeEditor)
import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P
import Gargantext.Components.Nodes.Dashboard.Types as DT
import Gargantext.Components.Nodes.Types (FTFieldList(..), FTFieldsWithIndex(..), defaultField)
......
This diff is collapsed.
......@@ -5,9 +5,9 @@ import Gargantext.Prelude
import Effect (Effect)
import Effect.Aff (launchAff_)
import Gargantext.Components.App.Store (Boxes)
import Gargantext.Components.Corpus.CodeSection (loadCorpusWithChild)
import Gargantext.Components.NgramsTable.Loader (clearCache)
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Nodes.Corpus (loadCorpusWithChild)
import Gargantext.Components.Nodes.Lists.Tabs as Tabs
import Gargantext.Components.Nodes.Lists.Types (CacheState(..))
import Gargantext.Components.Table as Table
......
......@@ -13,6 +13,7 @@ import Gargantext.Components.Bootstrap as B
import Gargantext.Components.Bootstrap.Types (Elevation(..))
import Gargantext.Components.Charts.Options.ECharts (dispatchAction)
import Gargantext.Components.Charts.Options.Type (EChartsInstance, EChartActionData)
import Gargantext.Components.Corpus.CodeSection (loadCorpusWithChild)
import Gargantext.Components.DocsTable as DT
import Gargantext.Components.DocsTable.Types (Year)
import Gargantext.Components.Document.API (loadData)
......@@ -20,10 +21,8 @@ import Gargantext.Components.Document.Layout (layout)
import Gargantext.Components.Document.Types (LoadedData, DocPath)
import Gargantext.Components.NgramsTable.Loader (clearCache)
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Nodes.Corpus (loadCorpusWithChild)
import Gargantext.Components.Nodes.Corpus.Chart.Histo (histo)
import Gargantext.Components.Nodes.Corpus.Chart.Types as CTypes
import Gargantext.Components.Nodes.Corpus.Document as D
import Gargantext.Components.Nodes.Corpus.Types (CorpusData)
import Gargantext.Components.Nodes.Lists.Types as LT
import Gargantext.Components.Nodes.Texts.Types as TT
......@@ -35,7 +34,7 @@ import Gargantext.Config.REST (logRESTError)
import Gargantext.Ends (Frontends)
import Gargantext.Hooks.Loader (useLoader, useLoaderEffect)
import Gargantext.Hooks.Session (useSession)
import Gargantext.Sessions (Session, getCacheState, sessionId)
import Gargantext.Sessions (Session, getCacheState)
import Gargantext.Types (CTabNgramType(..), ListId, NodeID, SidePanelState(..), TabSubType(..), TabType(..))
import Gargantext.Utils ((?))
import Gargantext.Utils.Reactix as R2
......
......@@ -170,8 +170,8 @@ editingCpt = here.component "editing" cpt where
T.write_ false isEditing
onRename text
onReset _ = do
T.write_ false isEditing
-- onReset _ = do
-- T.write_ false isEditing
-- | Render
-- |
......
This diff is collapsed.
This diff is collapsed.
module Gargantext.License where
import Reactix as R
import Reactix.DOM.HTML as H
license :: R.Element
license = H.p { className: "license" }
[ H.text "GarganText "
, H.span { className: "fa fa-registered"} []
, H.text " is made by "
, H.a { href: "https://iscpif.fr"
, target: "blank"
} [ H.text "CNRS/ISCPIF" ]
, H.a { href: "http://gitlab.iscpif.fr/humanities/gargantext/blob/stable/LICENSE"
, target: "blank"
, title: "Legal instructions of the project."
}
[ H.text ", with licences aGPLV3 and CECILL variant Affero compliant, " ]
, H.span { className: "fa fa-copyright" } []
, H.a { href: "https://cnrs.fr", target:"blank"} [H.text " CNRS 2017-Present "]
, H.text "."
]
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -93,3 +93,4 @@
&__type
width: 200px
margin-right: space-x(2)
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