--- /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: