Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Grégoire Locqueville
purescript-gargantext
Commits
480b3a61
Unverified
Commit
480b3a61
authored
Mar 19, 2019
by
Nicolas Pouillard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[NGRAMS-TABLE] prevent the creation of cycles
parent
fe8e89af
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
41 deletions
+61
-41
NgramsTable.purs
src/Gargantext/Components/NgramsTable.purs
+61
-41
No files found.
src/Gargantext/Components/NgramsTable.purs
View file @
480b3a61
...
...
@@ -28,11 +28,11 @@ import Data.Foldable (class Foldable, foldMap, foldl, foldr)
import Data.FoldableWithIndex (class FoldableWithIndex, foldMapWithIndex, foldlWithIndex, foldrWithIndex)
import Data.FunctorWithIndex (class FunctorWithIndex, mapWithIndex)
import Data.Newtype (class Newtype)
import Data.Lens (Iso', Lens', (
%~), (.=), (^.), (^..), to
)
import Data.Lens (Iso', Lens', (
?=), (%=), (%~), (.~), (^?), (^.), (^..), to, use, view
)
import Data.Lens.Common (_Just)
import Data.Lens.At (class At, at)
import Data.Lens.Index (class Index, ix)
import Data.Lens.Fold (folded)
import Data.Lens.Fold (folded
, traverseOf_
)
import Data.Lens.Record (prop)
import Data.Lens.Iso.Newtype (_Newtype)
import Data.List as List
...
...
@@ -95,10 +95,13 @@ newtype NgramsElement = NgramsElement
, list :: TermList
, occurrences :: Int
, parent :: Maybe NgramsTerm
, root :: Maybe NgramsTerm
, children :: Set NgramsTerm
}
_parent = prop (SProxy :: SProxy "parent")
_root = prop (SProxy :: SProxy "root")
_ngrams = prop (SProxy :: SProxy "ngrams")
_children :: forall row. Lens' { children :: Set NgramsTerm | row } (Set NgramsTerm)
_children = prop (SProxy :: SProxy "children")
_occurrences :: forall row. Lens' { occurrences :: Int | row } Int
...
...
@@ -118,9 +121,10 @@ instance decodeJsonNgramsElement :: DecodeJson NgramsElement where
list <- obj .? "list"
occurrences <- obj .? "occurrences"
parent <- obj .?? "parent"
root <- obj .?? "root"
children' <- obj .? "children"
let children = Set.fromFoldable (children' :: Array NgramsTerm)
pure $ NgramsElement {ngrams, list, occurrences, parent, children}
pure $ NgramsElement {ngrams, list, occurrences, parent,
root,
children}
type Version = Int
...
...
@@ -290,6 +294,7 @@ applyNgramsPatch (NgramsPatch p) (NgramsElement e) = NgramsElement
, list: applyReplace p.patch_list e.list
, occurrences: e.occurrences
, parent: e.parent
, root: e.root
, children: applyPatchSet p.patch_children e.children
}
...
...
@@ -351,11 +356,22 @@ applyPatchMap applyPatchValue (PatchMap p) = mapWithIndex f
type NgramsTablePatch = PatchMap NgramsTerm NgramsPatch
type RootParent = { root :: NgramsTerm, parent :: NgramsTerm }
type ReParent a = forall m. MonadState NgramsTable m => a -> m Unit
reParent :: Maybe NgramsTerm -> ReParent NgramsTerm
reParent parent child =
at child <<< _Just <<< _NgramsElement <<< _parent .= parent
reRootChildren :: NgramsTerm -> ReParent NgramsTerm
reRootChildren root ngram = do
nre <- use (at ngram)
traverseOf_ (_Just <<< _NgramsElement <<< _children <<< folded) (\child -> do
at child <<< _Just <<< _NgramsElement <<< _root ?= root
reRootChildren root child) nre
reParent :: Maybe RootParent -> ReParent NgramsTerm
reParent mrp child = do
at child <<< _Just <<< _NgramsElement %= ((_parent .~ (view _parent <$> mrp)) <<<
(_root .~ (view _root <$> mrp)))
reRootChildren (maybe child identity (mrp ^? _Just <<< _root)) child
-- reParentNgramsPatch :: NgramsTerm -> ReParent NgramsPatch
-- ^ GHC would have accepted this type. Here reParentNgramsPatch checks but
...
...
@@ -363,8 +379,13 @@ reParent parent child =
reParentNgramsPatch :: forall m. MonadState NgramsTable m
=> NgramsTerm -> NgramsPatch -> m Unit
reParentNgramsPatch parent (NgramsPatch {patch_children: PatchSet {rem, add}}) = do
-- root_of_parent <- use (at parent <<< _Just <<< _NgramsElement <<< _root)
-- ^ TODO this does not type checks, we do the following two lines instead:
s <- use (at parent)
let root_of_parent = s ^. (_Just <<< _NgramsElement <<< _root)
let rp = { root: maybe parent identity root_of_parent, parent }
traverse_ (reParent Nothing) rem
traverse_ (reParent $ Just
parent
) add
traverse_ (reParent $ Just
rp
) add
reParentNgramsTablePatch :: ReParent NgramsTablePatch
reParentNgramsTablePatch = void <<< traverseWithIndex reParentNgramsPatch
...
...
@@ -373,8 +394,6 @@ applyNgramsTablePatch :: NgramsTablePatch -> NgramsTable -> NgramsTable
applyNgramsTablePatch p (NgramsTable m) =
execState (reParentNgramsTablePatch p) $
NgramsTable $ applyPatchMap applyNgramsPatch p m
-- TODO: update the .root fields...
-- See ROOT-UPDATE
type State =
{ ngramsTablePatch :: NgramsTablePatch
...
...
@@ -494,9 +513,9 @@ tableContainer { pageParams
<<< _NgramsElement
<<< _children
%~ applyPatchSet (patchSetFromMap ngramsChildren)
ngramsClick
child
| child == ngrams = Nothing
| otherwise = Just $ dispatch $ ToggleChild false child
ngramsClick
{depth: 1, ngrams: child} =
Just $ dispatch $ ToggleChild false child
ngramsClick _ = Nothing
in
[ p[] [text $ "Editing " <> ngrams]
, renderNgramsTree { ngramsTable, ngrams, ngramsStyle: [], ngramsClick }
...
...
@@ -603,26 +622,22 @@ ngramsTableSpec = simpleSpec performAction render
loaderDispatch $ Loader.SetPath $ pageParams {params = params}
ngramsTable = applyNgramsTablePatch ngramsTablePatch initTable
rows = convertRow <$> Map.toUnfoldable (Map.filter displayRow (ngramsTable ^. _NgramsTable))
isRoot (NgramsElement e) = e.parent == Nothing
-- TODO: There is a missing case where we display a row that we should not.
-- Assumptions:
-- * cats -> cat -> animal
-- * We are editing cats: ngramsParent == Just "cats"
-- * animal should not be listed since this would create a cycle!
displayRow e@(NgramsElement {ngrams, children}) =
isRoot e
-- ^ Display only nodes with parents
&& (ngramsChildren ^. at ngrams /= Just true)
-- ^ and which are not scheduled to be added already.
&& (case ngramsParent of
Just p ->
ngrams /= p &&
-- ^ and which is not the node being currently edited.
not (Set.member p children)
-- ^ ... or one of its children.
Nothing -> true)
ngramsParentRoot :: Maybe String
ngramsParentRoot =
(\np -> ngramsTable ^. at np <<< _Just <<< _NgramsElement <<< _root) =<< ngramsParent
displayRow (NgramsElement {ngrams, root}) =
root == Nothing
-- ^ Display only nodes without parents
&& ngramsChildren ^. at ngrams /= Just true
-- ^ and which are not scheduled to be added already
&& Just ngrams /= ngramsParent
-- ^ and which are not our new parent
&& Just ngrams /= ngramsParentRoot
-- ^ and which are not the root of our new parent
|| -- Unless they are scheduled to be removed.
(ngramsChildren ^. at ngrams == Just false)
ngramsChildren ^. at ngrams == Just false
convertRow (Tuple ngrams ngramsElement) =
{ row:
renderNgramsItem { ngramsTable, ngrams, ngramsParent, ngramsElement, dispatch }
...
...
@@ -665,19 +680,22 @@ mainNgramsTableSpec = simpleSpec defaultPerformAction render
, component: ngramsTableClass
} ]
type NgramsDepth = {ngrams :: NgramsTerm, depth :: Int}
type NgramsClick = NgramsDepth -> Maybe (Effect Unit)
tree :: { ngramsTable :: NgramsTable
, ngramsStyle :: Array DOM.Props
, ngramsClick :: Ngrams
Term -> Maybe (Effect Unit)
} -> Ngrams
Term
-> ReactElement
tree params@{ngramsTable, ngramsStyle, ngramsClick}
label
=
, ngramsClick :: Ngrams
Click
} -> Ngrams
Depth
-> ReactElement
tree params@{ngramsTable, ngramsStyle, ngramsClick}
nd@{ngrams}
=
li [ style {width : "100%"} ]
[ i icon []
, tag [text $ " " <>
label
]
, tag [text $ " " <>
ngrams
]
, forest cs
]
where
tag =
case ngramsClick
label
of
case ngramsClick
nd
of
Just effect ->
a (ngramsStyle <> [onClick $ const effect])
Nothing ->
...
...
@@ -686,9 +704,11 @@ tree params@{ngramsTable, ngramsStyle, ngramsClick} label =
icon = gray <> [className $ "fas fa-caret-" <> if open then "down" else "right"]
open = not leaf || false {- TODO -}
gray = if leaf then [style {color: "#adb5bd"}] else []
cs = ngramsTable ^.. ix
label
<<< _NgramsElement <<< _children <<< folded
cs = ngramsTable ^.. ix
ngrams
<<< _NgramsElement <<< _children <<< folded
forest = ul [] <<< map (tree params) <<< List.toUnfoldable
forest =
let depth = nd.depth + 1 in
ul [] <<< map (\ngrams -> tree params {depth, ngrams}) <<< List.toUnfoldable
sumOccurrences' :: NgramsTable -> NgramsTerm -> Additive Int
sumOccurrences' ngramsTable label =
...
...
@@ -701,11 +721,11 @@ sumOccurrences ngramsTable (NgramsElement {occurrences, children}) =
renderNgramsTree :: { ngrams :: NgramsTerm
, ngramsTable :: NgramsTable
, ngramsStyle :: Array DOM.Props
, ngramsClick :: Ngrams
Term -> Maybe (Effect Unit)
, ngramsClick :: Ngrams
Click
} -> ReactElement
renderNgramsTree { ngramsTable, ngrams, ngramsStyle, ngramsClick } =
ul [] [
span [className "tree"] [tree {ngramsTable, ngramsStyle, ngramsClick}
ngrams
]
span [className "tree"] [tree {ngramsTable, ngramsStyle, ngramsClick}
{ngrams, depth: 0}
]
]
renderNgramsItem :: { ngrams :: NgramsTerm
...
...
@@ -730,7 +750,7 @@ renderNgramsItem { ngramsTable, ngrams, ngramsElement, ngramsParent, dispatch }
Additive occurrences = sumOccurrences ngramsTable ngramsElement
termList = ngramsElement ^. _NgramsElement <<< _list
ngramsStyle = [termStyle termList]
ngramsClick = Just <<< dispatch <<< SetParentResetChildren <<< Just
ngramsClick = Just <<< dispatch <<< SetParentResetChildren <<< Just
<<< view _ngrams
checkbox termList' =
let chkd = termList == termList'
termList'' = if chkd then CandidateTerm else termList'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment