src/main/scala/fis/crm/ui/ContactSnippet.scala
author Tomas Zeman <tzeman@volny.cz>
Tue, 23 Apr 2013 10:36:04 +0200
changeset 108 ef4e3e0ef83f
parent 93 8679b6804f4c
permissions -rw-r--r--
84a94fa29a67504b Task/Project notifications

/*
 * Copyright 2011-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.crm.ui

import fis.aaa.ui.IfLoggedIn
import fis.base.model._
import fis.base.ui._
import fis.crm.model._
import net.liftweb.common._
import net.liftweb.http._
import net.liftweb.record.Record
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 ContactSnippet extends ContactCrud with EntitySnippet[Contact] {
  val prefix = "contact"

  private val listPre = Menu("contact.list", l10n("Contacts")) / prefix >>
    Title(_ => i18n("Contacts")) >>
    locTpl("entity/list") >> Snippet("list", list)

  private val createPre = Menu("contact.create", l10n("Create")) / prefix / ADD >>
    Title(_ => i18n("Create contact")) >> IfLoggedIn.test >>
    locTpl("entity/form") >> Snippet("form", form) >> Hidden

  private val viewPre = Menu.param[Contact]("contact.view", l10n("Contact"), parse,
    encode) / prefix / * >> Title(c => i18n("Contact %s", c.linkName)) >>
    locTpl("contact/view") >> Snippet("panel", panel) >>
    Snippet("entities", entities) >> Hidden

  private val editPre = Menu.param[Contact]("contact.edit", l10n("Edit"), parse,
    encode) / prefix / * / EDIT >>
    Title(c => i18n("Edit contact %s", c.linkName)) >> IfLoggedIn.testVal >>
    locTpl("entity/form") >> Snippet("form", form) >> Hidden

  private val deletePre = Menu.param[Contact]("contact.delete", l10n("Delete"),
    parse, encode) / prefix / * / DELETE >>
    Title(c => i18n("Delete contact %s", c.linkName)) >> IfLoggedIn.testVal >>
    locTpl("entity/delete") >> Snippet("form", deleteF) >> Hidden

  private val listM = listPre >> SecNav(createPre).build
  private val createM = createPre >> SecNav(listPre).build
  private val viewM = viewPre >> (SecNav(editPre) + deletePre).build
  private val editM = editPre >> SecNav(viewPre).build
  private val deleteM = deletePre >> 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)

  private def list: CssTr = { _ => ContactTable(CrmSchema.allContacts) }

  private def panel: CssTr = "*" #> viewLoc.currentValue.map { ContactPanel(_) }

  private def entities: CssTr = "*" #> viewLoc.currentValue.map { c =>
    FieldTable[EntityWrapper[Contact]](_.fields, EntityWrapper(Contact.createRecord))(
      ContactEntities(c) map { e => EntityWrapper(e.asInstanceOf[Entity[Contact]]) })
  }

  private case class EntityWrapper[T <: Record[T]](e: Entity[T]) {
    val note = e.note
    val linkField = EntityLink(e)(scala.reflect.Manifest.classType(e.getClass))
    val typeField = new ReadOnlyField("type", l10n("Entity type"),
      i18n(e.getClass.getSimpleName), Empty)
    val fields = linkField.toSeq :+ typeField :+ note
  }

  object url {
    def view: Contact => Box[String] = (viewLoc.calcHref _) andThen (Box !! _)
  }

  private case class ContactLink(c: Contact) extends EntityLink[Contact](c,
    url.view) {
    override def displayName = l10n("contact.name")
  }

  EntityLink.register[Contact](ContactLink(_))

  private object form extends HorizontalScreen with CancelButton with SaveButton {

    object c extends ScreenVar[Contact](Contact.createRecord)

    override def screenFields: List[BaseField] = ContactPanel.fields(c)

    override def localSetup() {
      editLoc.currentValue.foreach(c(_))
    }

    def finish() { save(c) foreach { v =>
      S notice l10n("Contact %s saved.", v.linkName)
      S.redirectTo(viewLoc.calcHref(v))
    }}
  }

  private object deleteF extends HorizontalScreen with CancelButton with
    DeleteButton {

    val confirm = field(l10n("Really delete this contact?"), false)

    def finish() {
      for {
        c <- deleteLoc.currentValue if confirm
        r <- delete(c)
        n <- r.box(c.linkName)
      } {
        S notice l10n("Contact %s deleted.", n)
        S redirectTo listM.loc.calcDefaultHref
      }
    }
  }

}

// vim: set ts=2 sw=2 et: