Skip to content

Commit

Permalink
Updated TablePanel to the latest react features
Browse files Browse the repository at this point in the history
  • Loading branch information
viktor-podzigun committed Aug 21, 2019
1 parent 0209efd commit 7d1363b
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object TabPanelDemo extends FunctionComponent[Unit] {
})
)

<.div()(
<.>()(
<.h2()("TabPanel"),
<.p()("Demonstrates tabs functionality."),
<.p()(
Expand All @@ -36,6 +36,7 @@ object TabPanelDemo extends FunctionComponent[Unit] {
}
))()
),

<.h3()("Tabs on the left"),
<.p()(
<(TabPanel())(^.wrapped := TabPanelProps(
Expand All @@ -47,6 +48,7 @@ object TabPanelDemo extends FunctionComponent[Unit] {
direction = TabDirection.Left
))()
),

<.h3()("Tabs at the bottom"),
<.p()(
<(TabPanel())(^.wrapped := TabPanelProps(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,38 @@
package scommons.client.showcase.demo

import io.github.shogowada.scalajs.reactjs.React
import io.github.shogowada.scalajs.reactjs.VirtualDOM._
import io.github.shogowada.scalajs.reactjs.classes.ReactClass
import scommons.client.ui.table._
import scommons.react._
import scommons.react.hooks._

object TablePanelDemo {
object TablePanelDemo extends FunctionComponent[Unit] {

def apply(): ReactClass = reactClass

private lazy val reactClass = React.createClass[Unit, Unit] { _ =>
protected def render(props: Props): ReactElement = {
val (selectedIds, setSelectedIds) = useState(Set.empty[String])
val header = List(
TableColumnData("Id"),
TableColumnData("Name"),
TableColumnData("Description")
)

val rows = List(
TableRowData("1", List(
"1",
"1 row",
"1 test row"
)),
TableRowData("2", List(
"2",
"2 row",
"2 test row"
)),
TableRowData("3", List(
"3",
"3 row",
"3 test row"
))
TableRowData("1", List("1", "1 row", "1 test row")),
TableRowData("2", List("2", "2 row", "2 test row")),
TableRowData("3", List("3", "3 row", "3 test row"))
)

<.div()(
<.>()(
<.h2()("TablePanel"),
<.p()("Demonstrates table functionality."),
<.p()(
<(TablePanel())(^.wrapped := TablePanelProps(header, rows))()
<(TablePanel())(^.wrapped := TablePanelProps(
header = header,
rows = rows,
selectedIds = selectedIds,
onSelect = { data =>
setSelectedIds(Set(data.id))
}
))()
)
)
}
Expand Down
83 changes: 31 additions & 52 deletions ui/src/main/scala/scommons/client/ui/table/TablePanel.scala
Original file line number Diff line number Diff line change
@@ -1,74 +1,53 @@
package scommons.client.ui.table

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.events.MouseSyntheticEvent
import scommons.client.ui.table.TablePanelCss._
import scommons.react.UiComponent
import scommons.react._

case class TablePanelProps(header: List[TableColumnData],
rows: List[TableRowData],
selectedIds: Set[String] = Set.empty,
onSelect: TableRowData => Unit = _ => ())

object TablePanel extends UiComponent[TablePanelProps] {
object TablePanel extends FunctionComponent[TablePanelProps] {

private type TablePanelSelf = Self[PropsType, TablePanelState]
protected def render(compProps: Props): ReactElement = {
val props = compProps.wrapped

private case class TablePanelState(selectedIds: Set[String])

protected def create(): ReactClass = React.createClass[PropsType, TablePanelState](
getInitialState = { self =>
TablePanelState(self.props.wrapped.selectedIds)
},
componentWillReceiveProps = { (self, nextProps) =>
val props = nextProps.wrapped
if (self.props.wrapped.selectedIds != props.selectedIds) {
self.setState(_.copy(selectedIds = props.selectedIds))
}
},
render = { self =>
val props = self.props.wrapped

val tableHeader = props.header.map { column =>
<.th(^.colspan := 1)(column.title)
}

val tableBody = props.rows.map { row =>
val rowClass =
if (isRowSelected(self.state, row)) tablePanelSelectedRow
else tablePanelRow

<.tr(
^.className := rowClass,
^.onClick := rowClick(self, row)
)(row.cells.map { cell =>
<.td()(cell)
})
}
val tableHeader = props.header.map { column =>
<.th(^.colspan := 1)(column.title)
}

<.table(^.className := "table table-condensed", ^("cellSpacing") := "0")(
<.thead(^("aria-hidden") := "false")(
<.tr()(tableHeader)
),
<.tbody()(tableBody)
)
val tableBody = props.rows.map { row =>
val rowClass =
if (isRowSelected(props, row)) tablePanelSelectedRow
else tablePanelRow

<.tr(
^.className := rowClass,
^.onClick := rowClick(props, row)
)(row.cells.map { cell =>
<.td()(cell)
})
}
)

private def isRowSelected(state: TablePanelState, row: TableRowData): Boolean = {
state.selectedIds.contains(row.id)
<.table(^.className := "table table-condensed", ^("cellSpacing") := "0")(
<.thead(^("aria-hidden") := "false")(
<.tr()(tableHeader)
),
<.tbody()(tableBody)
)
}

private def rowClick(self: TablePanelSelf, row: TableRowData): MouseSyntheticEvent => Unit = { _ =>
if (!isRowSelected(self.state, row)) {
//event.stopPropagation()
private def isRowSelected(props: TablePanelProps, row: TableRowData): Boolean = {
props.selectedIds.contains(row.id)
}

self.setState(s => s.copy(selectedIds = Set(row.id)))
private def rowClick(props: TablePanelProps, row: TableRowData): MouseSyntheticEvent => Unit = { _ =>
if (!isRowSelected(props, row)) {
//event.stopPropagation()

self.props.wrapped.onSelect(row)
props.onSelect(row)
}
}
}
8 changes: 5 additions & 3 deletions ui/src/test/scala/scommons/client/ui/tab/TabPanelSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class TabPanelSpec extends TestSpec
with ShallowRendererUtils
with TestDOMUtils {

it should "call onSelect when select new tab" in {
it should "call onSelect only once" in {
//given
val onSelect = mockFunction[TabItemData, Int, Unit]
val items = List(
Expand All @@ -34,10 +34,12 @@ class TabPanelSpec extends TestSpec
val nextSelectIndex = 1

//then
onSelect.expects(items(nextSelectIndex), nextSelectIndex)
onSelect.expects(items(nextSelectIndex), nextSelectIndex).once()

//when
//when click on new item
fireDomEvent(Simulate.click(buttons(nextSelectIndex)))

//when click on selected item
fireDomEvent(Simulate.click(buttons(props.selectedIndex)))
}

Expand Down
32 changes: 17 additions & 15 deletions ui/src/test/scala/scommons/client/ui/table/TablePanelSpec.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package scommons.client.ui.table

import org.scalajs.dom
import org.scalatest.Succeeded
import scommons.client.ui.table.TablePanelCss._
import scommons.react.test.TestSpec
import scommons.react.test.dom.raw.ReactTestUtils
import scommons.react.test.dom.raw.ReactTestUtils._
import scommons.react.test.dom.util.TestDOMUtils
import scommons.react.test.raw.ShallowInstance
import scommons.react.test.util.ShallowRendererUtils

class TablePanelSpec extends TestSpec with ShallowRendererUtils {
class TablePanelSpec extends TestSpec
with ShallowRendererUtils
with TestDOMUtils {

it should "call onSelect once and select row when click on row" in {
it should "call onSelect only once" in {
//given
val onSelect = mockFunction[TableRowData, Unit]
val props = TablePanelProps(List(
Expand All @@ -19,25 +21,25 @@ class TablePanelSpec extends TestSpec with ShallowRendererUtils {
), List(
TableRowData("1", List("Cell1.1", "Cell1.2")),
TableRowData("2", List("Cell2.1", "Cell2.2"))
), onSelect = onSelect)
val comp = renderIntoDocument(<(TablePanel())(^.wrapped := props)())
val rows = scryRenderedDOMComponentsWithClass(comp, tablePanelRow)
), selectedIds = Set("1"), onSelect = onSelect)
domRender(<(TablePanel())(^.wrapped := props)())
val rows = domContainer.querySelectorAll("tbody > tr")
rows.length shouldBe props.rows.size
val nextSelectIndex = 0
val nextSelectIndex = 1
rows(0).asInstanceOf[dom.Element].getAttribute("class") shouldBe tablePanelSelectedRow
rows(nextSelectIndex).asInstanceOf[dom.Element].getAttribute("class") shouldBe tablePanelRow

//then
onSelect.expects(props.rows(nextSelectIndex)).once()

//when & then
ReactTestUtils.Simulate.click(rows(nextSelectIndex))
rows(nextSelectIndex).className shouldBe tablePanelSelectedRow
//when click on new row
fireDomEvent(Simulate.click(rows(nextSelectIndex)))

//when & then
ReactTestUtils.Simulate.click(rows(nextSelectIndex))
rows(nextSelectIndex).className shouldBe tablePanelSelectedRow
//when click on selected row
fireDomEvent(Simulate.click(rows(0)))
}

it should "reset selectedIds when componentWillReceiveProps" in {
it should "select rows with selectedIds when update" in {
//given
val prevProps = TablePanelProps(List(
TableColumnData("Col1"),
Expand Down

0 comments on commit 7d1363b

Please sign in to comment.