Skip to content

Commit

Permalink
Updated CheckBoxTree to the latest react features
Browse files Browse the repository at this point in the history
  • Loading branch information
viktor-podzigun committed Aug 27, 2019
1 parent 149d6fb commit 0b618a7
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 53 deletions.
20 changes: 8 additions & 12 deletions ui/src/main/scala/scommons/client/ui/tree/CheckBoxTree.scala
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
package scommons.client.ui.tree

import io.github.shogowada.scalajs.reactjs.React
import io.github.shogowada.scalajs.reactjs.React.Self
import io.github.shogowada.scalajs.reactjs.VirtualDOM._
import io.github.shogowada.scalajs.reactjs.classes.ReactClass
import io.github.shogowada.scalajs.reactjs.elements.ReactElement
import scommons.client.ui.{ImageCheckBox, ImageCheckBoxProps, TriState}
import scommons.client.ui.tree.TreeCss._
import scommons.react.UiComponent
import scommons.client.ui.{ImageCheckBox, ImageCheckBoxProps, TriState}
import scommons.react._

case class CheckBoxTreeProps(roots: List[CheckBoxTreeData],
onChange: (CheckBoxTreeData, TriState) => Unit = (_, _) => (),
readOnly: Boolean = false,
openNodes: Set[String] = Set.empty,
closeNodes: Set[String] = Set.empty)

object CheckBoxTree extends UiComponent[CheckBoxTreeProps] {
object CheckBoxTree extends ClassComponent[CheckBoxTreeProps] {

private case class CheckBoxTreeState(opened: Set[String])

protected def create(): ReactClass = React.createClass[PropsType, CheckBoxTreeState](
protected def create(): ReactClass = createClass[CheckBoxTreeState](
getInitialState = { self =>
val props = self.props.wrapped
CheckBoxTreeState(props.openNodes -- props.closeNodes)
},
componentWillReceiveProps = { (self, nextProps) =>
val props = nextProps.wrapped
if (self.props.wrapped.openNodes != props.openNodes) {
componentDidUpdate = { (self, prevProps, _) =>
val props = self.props.wrapped
if (props.openNodes != prevProps.wrapped.openNodes) {
val currKeys = CheckBoxTreeData.flattenNodes(props.roots).map(_.key).toSet
self.setState(s => s.copy(opened = (s.opened ++ props.openNodes).intersect(currKeys)))
}
if (self.props.wrapped.closeNodes != props.closeNodes) {
if (props.closeNodes != prevProps.wrapped.closeNodes) {
val currKeys = CheckBoxTreeData.flattenNodes(props.roots).map(_.key).toSet
self.setState(s => s.copy(opened = (s.opened -- props.closeNodes).intersect(currKeys)))
}
Expand Down
81 changes: 40 additions & 41 deletions ui/src/test/scala/scommons/client/ui/tree/CheckBoxTreeSpec.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package scommons.client.ui.tree

import io.github.shogowada.scalajs.reactjs.React
import org.scalatest.Assertion
import scommons.client.ui.TriState._
import scommons.client.ui._
import scommons.client.ui.tree.TreeCss._
import scommons.react._
import scommons.react.test.TestSpec
import scommons.react.test.dom.util.TestDOMUtils
import scommons.react.test.util.ShallowRendererUtils

class CheckBoxTreeSpec extends TestSpec with ShallowRendererUtils {
class CheckBoxTreeSpec extends TestSpec
with ShallowRendererUtils
with TestDOMUtils {

it should "expand node when onExpand" in {
//given
Expand Down Expand Up @@ -73,10 +76,13 @@ class CheckBoxTreeSpec extends TestSpec with ShallowRendererUtils {
val data = CheckBoxTreeItemData("test", Deselected, "/test")
val props = CheckBoxTreeProps(List(data), onChange = onChange)
val comp = shallowRender(<(CheckBoxTree())(^.wrapped := props)())
val checkBoxWrapper = React.createClass[Unit, Unit] { _ =>
findComponentProps(comp, TreeNode).renderValue()
val nodeProps = findComponentProps(comp, TreeNode)
val checkBoxWrapper = new FunctionComponent[Unit] {
protected def render(props: Props): ReactElement = {
nodeProps.renderValue()
}
}
val result = shallowRender(<(checkBoxWrapper).empty)
val result = shallowRender(<(checkBoxWrapper()).empty)
val checkBoxProps = findComponentProps(result, ImageCheckBox)

//then
Expand All @@ -91,12 +97,15 @@ class CheckBoxTreeSpec extends TestSpec with ShallowRendererUtils {
val data = CheckBoxTreeItemData("test", Deselected, "/test")
val props = CheckBoxTreeProps(List(data))
val comp = shallowRender(<(CheckBoxTree())(^.wrapped := props)())
val checkBoxWrapper = React.createClass[Unit, Unit] { _ =>
findComponentProps(comp, TreeNode).renderValue()
val nodeProps = findComponentProps(comp, TreeNode)
val checkBoxWrapper = new FunctionComponent[Unit] {
protected def render(props: Props): ReactElement = {
nodeProps.renderValue()
}
}

//when
val result = shallowRender(<(checkBoxWrapper).empty)
val result = shallowRender(<(checkBoxWrapper()).empty)

//then
assertCheckBox(findComponentProps(result, ImageCheckBox), props, data)
Expand All @@ -107,12 +116,15 @@ class CheckBoxTreeSpec extends TestSpec with ShallowRendererUtils {
val data = CheckBoxTreeItemData("test", Selected, "/test", Some(ButtonImagesCss.folder))
val props = CheckBoxTreeProps(List(data), readOnly = true)
val comp = shallowRender(<(CheckBoxTree())(^.wrapped := props)())
val checkBoxWrapper = React.createClass[Unit, Unit] { _ =>
findComponentProps(comp, TreeNode).renderValue()
val nodeProps = findComponentProps(comp, TreeNode)
val checkBoxWrapper = new FunctionComponent[Unit] {
protected def render(props: Props): ReactElement = {
nodeProps.renderValue()
}
}

//when
val result = shallowRender(<(checkBoxWrapper).empty)
val result = shallowRender(<(checkBoxWrapper()).empty)

//then
assertCheckBox(findComponentProps(result, ImageCheckBox), props, data)
Expand All @@ -131,69 +143,56 @@ class CheckBoxTreeSpec extends TestSpec with ShallowRendererUtils {
assertTreeNode(findComponentProps(result, TreeNode), props, data)
}

it should "render opened node when componentWillReceiveProps" in {
it should "render opened node when update" in {
//given
val node1 = CheckBoxTreeNodeData("node 1", Deselected, "/node-1")
val prevProps = CheckBoxTreeProps(List(node1), openNodes = Set(node1.key))
val renderer = createRenderer()
renderer.render(<(CheckBoxTree())(^.wrapped := prevProps)())
val comp = renderer.getRenderOutput()
findComponentProps(comp, TreeNode).arrowClass shouldBe treeOpenArrow
domRender(<(CheckBoxTree())(^.wrapped := prevProps)())
domContainer.querySelectorAll(s".$treeOpenArrow").length shouldBe 1
val node2 = CheckBoxTreeNodeData("node 2", Deselected, "/node-2")
val props = CheckBoxTreeProps(List(node1, node2), openNodes = Set(node2.key))

//when
renderer.render(<(CheckBoxTree())(^.wrapped := props)())
domRender(<(CheckBoxTree())(^.wrapped := props)())

//then
findProps(renderer.getRenderOutput(), TreeNode).map(_.arrowClass) shouldBe List(
treeOpenArrow,
treeOpenArrow
)
domContainer.querySelectorAll(s".$treeOpenArrow").length shouldBe 2
}

it should "render closed node when componentWillReceiveProps" in {
it should "render closed node when update" in {
//given
val node1 = CheckBoxTreeNodeData("node 1", Deselected, "/node-1")
val prevProps = CheckBoxTreeProps(List(node1), openNodes = Set(node1.key))
val renderer = createRenderer()
renderer.render(<(CheckBoxTree())(^.wrapped := prevProps)())
val comp = renderer.getRenderOutput()
findComponentProps(comp, TreeNode).arrowClass shouldBe treeOpenArrow
domRender(<(CheckBoxTree())(^.wrapped := prevProps)())
domContainer.querySelectorAll(s".$treeOpenArrow").length shouldBe 1
val node2 = CheckBoxTreeNodeData("node 2", Deselected, "/node-2")
val props = CheckBoxTreeProps(List(node1, node2), closeNodes = Set(node1.key))

//when
renderer.render(<(CheckBoxTree())(^.wrapped := props)())
domRender(<(CheckBoxTree())(^.wrapped := props)())

//then
findProps(renderer.getRenderOutput(), TreeNode).map(_.arrowClass) shouldBe List(
treeClosedArrow,
treeClosedArrow
)
domContainer.querySelectorAll(s".$treeClosedArrow").length shouldBe 2
}

it should "not render opened node when it was removed" in {
//given
val renderer = createRenderer()
val node1 = CheckBoxTreeNodeData("node 1", Deselected, "/node-1")
val props = CheckBoxTreeProps(List(node1), openNodes = Set(node1.key))
renderer.render(<(CheckBoxTree())(^.wrapped := props)())
findComponentProps(renderer.getRenderOutput(), TreeNode).arrowClass shouldBe treeOpenArrow
domRender(<(CheckBoxTree())(^.wrapped := props)())
domContainer.querySelectorAll(s".$treeOpenArrow").length shouldBe 1
val node2 = CheckBoxTreeNodeData("node 2", Deselected, "/node-2")
val propsV2 = CheckBoxTreeProps(List(node2), openNodes = Set(node2.key))
renderer.render(<(CheckBoxTree())(^.wrapped := propsV2)())
findComponentProps(renderer.getRenderOutput(), TreeNode).arrowClass shouldBe treeOpenArrow
domRender(<(CheckBoxTree())(^.wrapped := propsV2)())
domContainer.querySelectorAll(s".$treeOpenArrow").length shouldBe 1
val propsV3 = CheckBoxTreeProps(List(node1, node2))

//when
renderer.render(<(CheckBoxTree())(^.wrapped := propsV3)())
domRender(<(CheckBoxTree())(^.wrapped := propsV3)())

//then
findProps(renderer.getRenderOutput(), TreeNode).map(_.arrowClass) shouldBe List(
treeClosedArrow,
treeOpenArrow
)
domContainer.querySelectorAll(s".$treeClosedArrow").length shouldBe 1
domContainer.querySelectorAll(s".$treeOpenArrow").length shouldBe 1
}

it should "render opened child nodes" in {
Expand Down

0 comments on commit 0b618a7

Please sign in to comment.