/*
* Copyright 2012 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 fis.pm.ui
import fis.aaa.ui.IfLoggedIn
import fis.base.ui._
import fis.crm.model._
import fis.pm.model._
import net.liftweb.common._
import net.liftweb.http._
import net.liftweb.record.field._
import net.liftweb.sitemap._
import net.liftweb.sitemap.Loc._
import net.liftweb.util._
import net.liftweb.util.Helpers._
import net.tz.lift.model._
import net.tz.lift.snippet._
import scala.xml.{Elem, NodeSeq, Text}
object ProjectSnippet extends ProjectCrud with EntitySnippet[Project] {
val prefix = "project"
private val listPre = Menu("project.list", l10n("Projects")) / prefix >>
Title(_ => i18n("Projects")) >>
locTpl("entity/list") >> Snippet("list", list)
private val createPre = Menu("project.create", l10n("Create")) / prefix / ADD >>
Title(_ => i18n("Create project")) >> IfLoggedIn.test >>
locTpl("entity/form") >> Snippet("form", form) >> Hidden
private val viewPre = Menu.param[Project]("project.view", l10n("Project"), parse,
encode) / prefix / * >> Title(p => i18n("Project %s", p.linkName)) >>
locTpl("project/view") >> Snippet("panel", panel) >>
Snippet("tasks", tasks) >> Hidden
private val editPre = Menu.param[Project]("project.edit", l10n("Edit"), parse,
encode) / prefix / * / EDIT >>
Title(p => i18n("Edit project %s", p.linkName)) >> IfLoggedIn.testVal >>
locTpl("entity/form") >> Snippet("form", form) >> Hidden
private val deletePre = Menu.param[Project]("project.delete", l10n("Delete"),
parse, encode) / prefix / * / DELETE >>
Title(p => i18n("Delete project %s", p.linkName)) >> IfLoggedIn.testVal >>
locTpl("entity/delete") >> Snippet("form", deleteF) >> Hidden
private val createTaskPre = Menu.param[Project]("project.create-task",
l10n("Create task"), parse, encode) / prefix / * / "create-task" >>
Title(p => i18n("Create task for project %s", p.linkName)) >>
IfLoggedIn.testVal >>
locTpl("entity/form") >> Snippet("form", taskF) >> Hidden
private val listM = listPre >> SecNav(createPre).build
private val createM = createPre >> SecNav(listPre).build
private val viewM = viewPre >> (SecNav(editPre) + deletePre +
createTaskPre).build
private val editM = editPre >> SecNav(viewPre).build
private val deleteM = deletePre >> SecNav(viewPre).build
private val createTaskM = createTaskPre >> SecNav(viewPre).build
private lazy val viewLoc = viewM.toLoc
private lazy val editLoc = editM.toLoc
private lazy val deleteLoc = deleteM.toLoc
val menu = listM submenus(viewM, editM, createM, deleteM, createTaskM)
private def cur = viewLoc.currentValue or editLoc.currentValue or
deleteLoc.currentValue
private def list: CssTr = { _ => ProjectTable(PmSchema.projects) }
private def panel: CssTr = "*" #> cur.map { p => ViewPanel(fields(p)) }
private def tasks: CssTr = "*" #> cur.map { p => TaskTable(ProjectTasks(p)) }
object url {
def view: Project => Box[String] = (viewLoc.calcHref _) andThen (Box !! _)
def list: String = listM.loc.calcDefaultHref
}
private def fields(p: Project) = List(p.name, p.identS, p.stateFld,
p.createdBy, p.createdAt, p.deadline, p.responsible, p.productLine,
ProjectCompanyField(p), p.description, p.note)
private case class ProjectLink(c: Project) extends EntityLink[Project](c, url.view)
EntityLink.register[Project](ProjectLink(_))
private case class ProjectCompanyField(p: Project) extends OptionalLongField(p)
with CompanyField with FieldLabel {
override def name = "company"
override def defaultValueBox =
PmSchema.projectCompany.left(p).headOption.map(_.id)
}
private object form extends HorizontalScreen with CancelButton with
SaveButton {
private object project extends ScreenVar[Project](Project.createRecord)
private object company extends ScreenVar[CompanyField](
ProjectCompanyField(project))
private def formFields(p: Project) = {
List(p.name, p.identS, p.stateFld, p.deadline, p.responsible,
p.productLine, company.get, p.description, p.note)
}
override def screenFields: List[BaseField] = formFields(project)
override def localSetup() {
cur.foreach { p => project(p); company(ProjectCompanyField(p)) }
}
def finish() {
save(project) foreach { p =>
val fk = PmSchema.projectCompany.left(p)
company.vend match {
case Full(c) if fk.exists(_.id == c.id) => // empty, no update
case Full(c) =>
fk.dissociateAll
fk.associate(c)
case _ => fk.dissociateAll
}
S notice l10n("Project %s saved.", p.linkName)
S.redirectTo(viewLoc.calcHref(p))
}
}
}
private object deleteF extends HorizontalScreen with CancelButton with
DeleteButton {
val confirm = field(l10n("Really delete this project?"), false)
def finish() {
for {
c <- deleteLoc.currentValue if confirm
r <- delete(c)
n <- r.box(c.linkName)
} {
S notice l10n("Project %s deleted.", n)
S redirectTo listM.loc.calcDefaultHref
}
}
}
private object taskF extends TaskForm {
override def localSetup() {
createTaskM.currentValue.foreach { p => task.project(p.id) }
}
protected def onSuccess(t: Task) {
TaskSnippet.url.view(t).foreach { u => S redirectTo u }
}
}
}
// vim: set ts=2 sw=2 et: