diff --git a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala index 7307d22..6c35c89 100644 --- a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala +++ b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala @@ -10,14 +10,30 @@ type ViewModel = List[UserRow.ViewModel] def apply($m: Signal[ViewModel]): HtmlElement = + val (actionsStream, actionObserver) = + EventStream.withObserver[SearchForm.Action] + val $filter = actionsStream + .collect { case ev: SearchForm.FilterAction => + ev + } + .startWith(SearchForm.NoFilter) val byLetter = for { d <- $m + f <- $filter } yield for { - (letter, users) <- d.groupBy(_.prijmeni.head).to(List).sortBy(_._1) + (letter, users) <- d + .filter { user => + f match + case SearchForm.NoFilter => true + case SearchForm.Filter(t) => user.search.contains(t) + } + .groupBy(_.prijmeni.head) + .to(List) + .sortBy(_._1) } yield (letter.toString, users.sortBy(_.prijmeni)) div( cls := "h-full max-w-7xl mx-auto order-first flex flex-col flex-shrink-0", - SearchForm(), + SearchForm(actionObserver), Directory(byLetter) ) diff --git a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala index 7307d22..6c35c89 100644 --- a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala +++ b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala @@ -10,14 +10,30 @@ type ViewModel = List[UserRow.ViewModel] def apply($m: Signal[ViewModel]): HtmlElement = + val (actionsStream, actionObserver) = + EventStream.withObserver[SearchForm.Action] + val $filter = actionsStream + .collect { case ev: SearchForm.FilterAction => + ev + } + .startWith(SearchForm.NoFilter) val byLetter = for { d <- $m + f <- $filter } yield for { - (letter, users) <- d.groupBy(_.prijmeni.head).to(List).sortBy(_._1) + (letter, users) <- d + .filter { user => + f match + case SearchForm.NoFilter => true + case SearchForm.Filter(t) => user.search.contains(t) + } + .groupBy(_.prijmeni.head) + .to(List) + .sortBy(_._1) } yield (letter.toString, users.sortBy(_.prijmeni)) div( cls := "h-full max-w-7xl mx-auto order-first flex flex-col flex-shrink-0", - SearchForm(), + SearchForm(actionObserver), Directory(byLetter) ) diff --git a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala index 7144950..7e1a5d9 100644 --- a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala +++ b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala @@ -4,7 +4,12 @@ import cz.e_bs.cmi.mdr.pdb.app.components.Icons object SearchForm: - def apply(): HtmlElement = + sealed trait Action + sealed trait FilterAction extends Action + case object NoFilter extends FilterAction + case class Filter(value: String) extends FilterAction + + def apply(actions: Observer[Action]): HtmlElement = div( cls := "px-6 pt-4 pb-4", form( @@ -15,7 +20,7 @@ label( forId := "search", cls := "sr-only", - """Search""" + "Hledat" ), div( cls := "relative rounded-md shadow-sm", @@ -28,7 +33,8 @@ name := "search", idAttr := "search", cls := "focus:ring-pink-500 focus:border-pink-500 block w-full pl-10 sm:text-sm border-gray-300 rounded-md", - placeholder := "Search" + placeholder := "Hledat", + onInput.mapToValue.setAsValue.map(Filter(_)) --> actions ) ) ), @@ -38,7 +44,7 @@ Icons.solid.filter().amend(svg.cls := "text-gray-400"), span( cls := "sr-only", - """Search""" + "Hledat" ) ) ) diff --git a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala index 7307d22..6c35c89 100644 --- a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala +++ b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/DirectoryPage.scala @@ -10,14 +10,30 @@ type ViewModel = List[UserRow.ViewModel] def apply($m: Signal[ViewModel]): HtmlElement = + val (actionsStream, actionObserver) = + EventStream.withObserver[SearchForm.Action] + val $filter = actionsStream + .collect { case ev: SearchForm.FilterAction => + ev + } + .startWith(SearchForm.NoFilter) val byLetter = for { d <- $m + f <- $filter } yield for { - (letter, users) <- d.groupBy(_.prijmeni.head).to(List).sortBy(_._1) + (letter, users) <- d + .filter { user => + f match + case SearchForm.NoFilter => true + case SearchForm.Filter(t) => user.search.contains(t) + } + .groupBy(_.prijmeni.head) + .to(List) + .sortBy(_._1) } yield (letter.toString, users.sortBy(_.prijmeni)) div( cls := "h-full max-w-7xl mx-auto order-first flex flex-col flex-shrink-0", - SearchForm(), + SearchForm(actionObserver), Directory(byLetter) ) diff --git a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala index 7144950..7e1a5d9 100644 --- a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala +++ b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/SearchForm.scala @@ -4,7 +4,12 @@ import cz.e_bs.cmi.mdr.pdb.app.components.Icons object SearchForm: - def apply(): HtmlElement = + sealed trait Action + sealed trait FilterAction extends Action + case object NoFilter extends FilterAction + case class Filter(value: String) extends FilterAction + + def apply(actions: Observer[Action]): HtmlElement = div( cls := "px-6 pt-4 pb-4", form( @@ -15,7 +20,7 @@ label( forId := "search", cls := "sr-only", - """Search""" + "Hledat" ), div( cls := "relative rounded-md shadow-sm", @@ -28,7 +33,8 @@ name := "search", idAttr := "search", cls := "focus:ring-pink-500 focus:border-pink-500 block w-full pl-10 sm:text-sm border-gray-300 rounded-md", - placeholder := "Search" + placeholder := "Hledat", + onInput.mapToValue.setAsValue.map(Filter(_)) --> actions ) ) ), @@ -38,7 +44,7 @@ Icons.solid.filter().amend(svg.cls := "text-gray-400"), span( cls := "sr-only", - """Search""" + "Hledat" ) ) ) diff --git a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/UserRow.scala b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/UserRow.scala index 39da83e..4e6f76d 100644 --- a/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/UserRow.scala +++ b/app/src/main/scala/cz/e_bs/cmi/mdr/pdb/app/pages/directory/components/UserRow.scala @@ -12,7 +12,9 @@ hlavniFunkce: Option[String], img: Option[String], container: HtmlElement = div() - ) + ) { + val search = prijmeni.toLowerCase + } def apply($m: Signal[ViewModel]): HtmlElement = inline def avatarImage =