diff -r 69e26359f2c8 -r cf829ec742b3 src/main/scala/radview/snippet/CellSnippet.scala --- /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 + * + * 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: