src/main/scala/radview/snippet/CellSnippet.scala
changeset 2 cf829ec742b3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/radview/snippet/CellSnippet.scala	Sun Apr 03 15:55:02 2011 +0200
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2011 Tomas Zeman <tzeman@volny.cz>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package radview.snippet
+
+import java.util.Date
+import net.liftweb.common._
+import net.liftweb.http._
+import net.liftweb.http.{RewriteRequest => RReq, RewriteResponse => RResp, ParsePath => PP}
+import net.liftweb.mapper._
+import net.liftweb.sitemap._
+import net.liftweb.sitemap.Loc._
+import net.liftweb.util._
+import net.liftweb.util.Helpers.{asInt, now}
+import net.tz.lift.snippet._
+import net.tz.lift.util._
+import org.joda.time.{DateMidnight, DateTime, Period}
+import radview.model.{Cdr, Cell}
+import scala.xml.{Elem, NodeSeq, Text}
+
+object AsCell {
+  def unapply(in: String): Option[Cell] = Cell.findByKey(in)
+  def unapply(in: CellLoc): Option[Cell] = in match {
+    case CellView(c) => Some(c)
+    case ActiveSessions(c) => Some(c)
+    case _ => None
+  }
+}
+
+abstract sealed class CellLoc
+case object NoSuchCell extends CellLoc
+case class CellView(c: Cell) extends CellLoc
+case object CellSearch extends CellLoc
+case class ActiveSessions(c: Cell) extends CellLoc 
+
+object CellSnippet extends Loc[CellLoc] with SnippetHelpers with Loggable {
+
+  val name = "cell"
+  val prefix = "cell"
+  val tpl = "cell"
+  val params = List(Hidden)
+  val defaultValue = Full(CellSearch)
+  val link = new Link[CellLoc](List(prefix), true) {
+    override def createPath(l: CellLoc): String = l match {
+      case CellView(c) => mkPath(prefix, c.idpk.is)
+      case ActiveSessions(c) => mkPath(prefix, c.idpk.is, "active-sessions")
+      case _ => prefix
+    }
+  }
+  def url(l: CellLoc) = link.createPath(l)
+
+  val text = LinkText[CellLoc](l => Text(l match {
+    case NoSuchCell => "No such cell"
+    case CellView(c) => "Cell " + c.btsName
+    case CellSearch => "Cell search"
+    case ActiveSessions(c) => "Active sessions on " + c.btsName
+  }))
+
+  import AsDateMidnight.d2dm
+
+  override def rewrite: LocRewrite = Full({
+    case RReq(PP("cell" :: AsCell(c) :: xs, _, _,_), _, _) => xs match {
+      case "active-sessions" :: Nil =>
+        ActionLinks append A(url(CellView(c)), "Back to cell")
+        (RResp(List(tpl, "view")), ActiveSessions(c))
+      case _ =>
+        ActionLinks append A(url(ActiveSessions(c)), "Active sessions")
+        (RResp(List(tpl, "view")), CellView(c))
+    }
+
+    case RReq(PP(List("cell"), _, _,_), _, _) =>
+      (RResp(List(tpl, "search")), CellSearch)
+  })
+
+  override def snippets: SnippetTest = {
+    case ("panel", Full(AsCell(c))) => CellPanel(c)
+
+    case ("form", Full(CellSearch)) => searchForm
+    case ("form", Full(ActiveSessions(_))) => activeSessionsForm
+    case ("list", Full(CellSearch)) => searchList
+    case ("list", Full(ActiveSessions(c))) => activeSessionsTable(c)
+
+    case ("panel", _) => ClearNodes
+    case ("form", _) => ClearNodes
+    case ("list", _) => ClearNodes
+  }
+
+  object mxCnt extends RequestVar[Int](100)
+  object searchField extends RequestVar[Box[Int]](Empty)
+  object searchValue extends RequestVar[String]("")
+
+  lazy val searchFields: List[MappedField[_, Cell]] = Cell.fieldsForSearch
+
+  def searchForm: (NodeSeq => NodeSeq) = {
+    import AttrRow.{formRow, submitRow}
+    SimpleForm(List(
+      formRow(SHtml.selectObj[Int](
+        searchFields.zipWithIndex.map(f => (f._2, f._1.displayName)),
+        searchField.is, { i => searchField(Full(i)) } ),
+        SHtml.textElem(searchValue)
+      ),
+      formRow(Text("Max. results"), SHtml.selectObj[Int](
+        List(100, 200, 500) map { i => (i, i.toString) }, Full(mxCnt.is),
+        mxCnt(_)))
+    ), "Search")
+  }
+
+  object from extends RequestVar[DateTime]((new DateTime).minusHours(1))
+  object to extends RequestVar[DateTime](new DateTime)
+  object runQuery extends RequestVar[Box[Any]](Empty)
+
+  def activeSessionsForm: (NodeSeq => NodeSeq) = {
+    object dateVal extends RequestVar[String](AsDateMidnight(from))
+    object fromT extends RequestVar[String](AsTimePeriod(from))
+    object toT extends RequestVar[String](AsTimePeriod(to))
+
+    def setD() = {
+      for {
+        d <- AsDateMidnight(dateVal)
+        f <- AsTimePeriod(fromT)
+        t <- AsTimePeriod(toT)
+      } yield {
+        from(d.toDateTime.plus(f))
+        to(d.toDateTime.plus(t))
+      }
+      dateVal(AsDateMidnight(from))
+      fromT(AsTimePeriod(from))
+      toT(AsTimePeriod(to))
+      runQuery(Full(1))
+    }
+
+    import AttrRow._
+    SimpleForm(List(
+      formRow(Text("Date"), SHtml.textElem(dateVal, ("class", "date"))),
+      formRow(Text("Time from"), SHtml.textElem(fromT)),
+      formRow(Text("Time to"), SHtml.textElem(toT))), "Submit", setD)
+  }
+
+  def qp(f: MappedField[_, Cell], v: String): Box[QueryParam[Cell]] = {
+    val strCls = classOf[String]
+    val intCls = classOf[Int]
+    val clz = f.dbFieldClass
+    f match {
+      case fx: MappedField[String, Cell] if clz == classOf[String] =>
+        Full(Like(fx, "%" + v + "%"))
+      case fx: MappedField[Int, Cell] if clz == classOf[Int] =>
+        asInt(v) map { By(fx, _) }
+      case _ => Empty
+    }
+  }
+
+  def searchList: (NodeSeq => NodeSeq) = searchField.is map { idx =>
+    val rows = searchValue.is match {
+      case "" | null => Nil
+      case v =>
+        qp(searchFields(idx), v) map { p =>
+          Cell.findAll(p, OrderBy(Cell.btsName, Ascending), MaxRows(mxCnt.is))
+        } openOr Nil
+    }
+    Table[Cell](Cell.fieldsForList.map(f => Column[Cell](f.displayName,
+      {i: Cell => f.actualField(i).asHtml})), rows)
+  } openOr ClearNodes
+
+
+  def activeSessionsTable(c: Cell): (NodeSeq => NodeSeq) = runQuery map { v =>
+    import AsDateMidnight.dt2d
+    val sess1 = Cdr.findAllFields(List(Cdr.sid),
+      By_<(Cdr.ts, to.plusMinutes(1)),
+      By_>(Cdr.ts, from.minusMinutes(1)), By(Cdr.cell, c.idpk), Distinct[Cdr])
+    val sessions = Cdr.sessions(sess1 map { _.sid.is })
+    CdrSessionTable(sessions)
+  } openOr ClearNodes
+
+}
+
+object CellPanel {
+  def apply(c: Cell): (NodeSeq => NodeSeq) =
+    Panel.fromFields(c.fieldsForDisplay)
+}
+
+// vim: set ts=2 sw=2 et: