# HG changeset patch # User Tomas Zeman # Date 1334903182 -7200 # Node ID e2a2e2045c0ec3b8269cf0f36ca0cd29563e23d3 # Parent 9e35765f46699fd7122c4d5f3440a0d51d0ad4fe User UI diff -r 9e35765f4669 -r e2a2e2045c0e src/main/scala/bootstrap/liftweb/Boot.scala --- a/src/main/scala/bootstrap/liftweb/Boot.scala Fri Apr 20 08:26:06 2012 +0200 +++ b/src/main/scala/bootstrap/liftweb/Boot.scala Fri Apr 20 08:26:22 2012 +0200 @@ -17,6 +17,7 @@ import fis.base.model._ import fis.base.ui._ +import fis.aaa.ui.UserSnippet import fis.crm.ui.ContactSnippet import fis.db.SquerylTxMgr import net.liftweb.common._ @@ -40,7 +41,8 @@ SecNav.init() val menus = List(Menu("/", "FIS Main page") / "index" >> Hidden, - Menu.i("Home") / "" , ContactSnippet.menu) + Menu.i("Home") / "" , ContactSnippet.menu, + UserSnippet.menu) LiftRules.setSiteMap(SiteMap(menus:_*)) diff -r 9e35765f4669 -r e2a2e2045c0e src/main/scala/fis/aaa/model/User.scala --- a/src/main/scala/fis/aaa/model/User.scala Fri Apr 20 08:26:06 2012 +0200 +++ b/src/main/scala/fis/aaa/model/User.scala Fri Apr 20 08:26:22 2012 +0200 @@ -30,7 +30,7 @@ def meta = User val login = new StringField(this, 40) with FL - val password = new PasswordField(this) with FL + val password = new StringField(this, 128) with FL val active = new BooleanField(this) with FL { override def defaultValue = true } diff -r 9e35765f4669 -r e2a2e2045c0e src/main/scala/fis/aaa/ui/UserPanel.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/aaa/ui/UserPanel.scala Fri Apr 20 08:26:22 2012 +0200 @@ -0,0 +1,29 @@ +/* + * Copyright 2011-2012 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 fis.aaa.ui + +import fis.aaa.model._ +import fis.base.ui.ViewPanel +import net.liftweb.util.BaseField + +object UserPanel { + + def fields(u: User): List[BaseField] = List(u.name, u.login, u.active, u.note) + + def apply(u: User) = ViewPanel(fields(u)) +} + +// vim: set ts=2 sw=2 et: diff -r 9e35765f4669 -r e2a2e2045c0e src/main/scala/fis/aaa/ui/UserSnippet.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/aaa/ui/UserSnippet.scala Fri Apr 20 08:26:22 2012 +0200 @@ -0,0 +1,148 @@ +/* + * Copyright 2011-2012 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 fis.aaa.ui + +import fis.base.ui._ +import fis.aaa.model._ +import net.liftweb.common._ +import net.liftweb.http._ +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 UserSnippet extends UserCrud with EntitySnippet[User] { + val prefix = "user" + + private val listPre = Menu("user.list", l10n("Users")) / prefix >> + Title(_ => i18n("Users")) >> + locTpl("entity/list") >> Snippet("list", list) + + private val createPre = Menu("user.create", l10n("Create")) / prefix / ADD >> + Title(_ => i18n("Create user")) >> + locTpl("entity/form") >> Snippet("form", form) >> Hidden + + private val viewPre = Menu.param[User]("user.view", l10n("User"), parse, + encode) / prefix / * >> Title(c => i18n("User %s", c.linkName)) >> + locTpl("entity/view") >> Snippet("panel", panel) >> Hidden + + private val editPre = Menu.param[User]("user.edit", l10n("Edit"), parse, + encode) / prefix / * / EDIT >> + Title(c => i18n("Edit user %s", c.linkName)) >> + locTpl("entity/form") >> Snippet("form", form) >> Hidden + + private val deletePre = Menu.param[User]("user.delete", l10n("Delete"), + parse, encode) / prefix / * / DELETE >> + Title(c => i18n("Delete user %s", c.linkName)) >> + 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 cur = viewLoc.currentValue or editLoc.currentValue or + deleteLoc.currentValue + + private def list: CssTr = { _ => UserTable(AaaSchema.usersF()) } + + private def panel: CssTr = "*" #> cur.map(UserPanel(_)) + + object url { + def view: User => Box[String] = (viewLoc.calcHref _) andThen (Box !! _) + } + + private case class UserLink(u: User) extends EntityLink[User](u, url.view) { + override def displayName = l10n("user.name") + } + + EntityLink.register[User](UserLink(_)) + + private object form extends HorizontalScreen with CancelButton with SaveButton { + + private object user extends ScreenVar[User](User.createRecord) + + val pass1 = password(User.password.displayName, User.password.defaultValue) + val pass2 = password(l10n("user.password.repeat"), + User.password.defaultValue) + + private def validatePass: List[FieldError] = (pass1.get != pass2.get).box { + FieldError(pass2, i18n("Passwords do not match.")) } toList + + private def roText(f: BaseField) = new Field { + type ValueType = String + def default = "" + override def name = f.name + override def displayName = f.displayName + override def toForm = Full({f.asHtml}) + override implicit def manifest = buildIt[String] + } + + private def fields(u: User): List[FieldContainer] = { + val n_l = List(u.name, u.login) + val n_l_f = (u.id != u.idField.defaultValue).box(n_l map { roText _ }). + openOr(n_l) + + n_l_f ++ List[FieldContainer](pass1, pass2, u.active, u.note) + } + + override def screenFields: List[BaseField] = + fields(user) flatMap(_.allFields) + + override def validations = validatePass _ :: super.validations + + override def localSetup() { + cur.foreach(user(_)) + } + + def finish() { + (pass1.get.length > 0).box(user.password(md5(pass1.get))) + save(user) foreach { v => + S notice l10n("User %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 user?"), false) + + def finish() { + for { + u <- cur if confirm + r <- save(u.deleted(true)) + } { + S notice l10n("User %s deleted", r.linkName) + S redirectTo listM.loc.calcDefaultHref + } + } + } + +} + +// vim: set ts=2 sw=2 et: diff -r 9e35765f4669 -r e2a2e2045c0e src/main/scala/fis/aaa/ui/UserTable.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/aaa/ui/UserTable.scala Fri Apr 20 08:26:22 2012 +0200 @@ -0,0 +1,30 @@ +/* + * Copyright 2011-2012 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 fis.aaa.ui + +import fis.aaa.model._ +import fis.base.ui._ +import net.liftweb.common._ +import net.tz.lift.model._ + +object UserTable extends FieldTable[User] { + def fields(u: User) = EntityLink(u) ++ Seq(u.login, u.active, u.note) + + def apply(l: Iterable[User]) = build(User, l) +} + + +// vim: set ts=2 sw=2 et: