# HG changeset patch # User Tomas Zeman # Date 1335529414 -7200 # Node ID f7553032b302928931fdabbfb4389e2968f18cc4 # Parent ad2fe2f9bac75161fad20091078ccd374635afe2 Comment diff -r ad2fe2f9bac7 -r f7553032b302 db/db-schema.sql --- a/db/db-schema.sql Fri Apr 27 14:15:51 2012 +0200 +++ b/db/db-schema.sql Fri Apr 27 14:23:34 2012 +0200 @@ -190,6 +190,17 @@ "updated_by" bigint ); create sequence "task_id_seq"; +create table "comment" ( + "name" varchar(100) not null, + "updated_at" timestamp not null, + "task_id" bigint not null, + "id" bigint primary key not null, + "note" varchar(10240), + "created_at" timestamp not null, + "created_by" bigint, + "updated_by" bigint + ); +create sequence "comment_id_seq"; -- foreign key constraints : alter table "address" add constraint "addressFK1" foreign key ("city_id") references "city"("id"); alter table "city" add constraint "cityFK2" foreign key ("country_id") references "country"("id"); @@ -204,6 +215,7 @@ alter table "task" add constraint "taskFK15" foreign key ("task_type") references "code_list_item"("id"); alter table "task" add constraint "taskFK16" foreign key ("state") references "code_list_item"("id"); alter table "task" add constraint "taskFK17" foreign key ("project_id") references "project"("id"); +alter table "comment" add constraint "commentFK18" foreign key ("task_id") references "task"("id") on delete cascade; alter table "company_contact" add constraint "company_contactFK7" foreign key ("entity") references "company"("id") on delete cascade; alter table "company_contact" add constraint "company_contactFK8" foreign key ("contact") references "contact"("id") on delete cascade; alter table "user_contact" add constraint "user_contactFK9" foreign key ("entity") references "user"("id") on delete cascade; diff -r ad2fe2f9bac7 -r f7553032b302 src/main/scala/fis/pm/model/Comment.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/model/Comment.scala Fri Apr 27 14:23:34 2012 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright 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.pm.model + +import fis.aaa.model._ +import fis.base.model.Entity +import fis.cl.model._ +import net.liftweb.common._ +import net.liftweb.record.{MetaRecord, Record} +import net.liftweb.record.field._ +import net.liftweb.util._ +import net.tz.lift.model._ +import net.tz.lift.model.{FieldLabel => FL} +import org.squeryl.annotations.Column +import scala.xml.Text + +class Comment private() extends Record[Comment] with Entity[Comment] { + def meta = Comment + + @Column("task_id") + val task = new LongField(this) +} + +object Comment extends Comment with MetaRecord[Comment] + +// vim: set ts=2 sw=2 et: diff -r ad2fe2f9bac7 -r f7553032b302 src/main/scala/fis/pm/model/CommentCrud.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/model/CommentCrud.scala Fri Apr 27 14:23:34 2012 +0200 @@ -0,0 +1,26 @@ +/* + * Copyright 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.pm.model + +import fis.base.model.RecordCrud + +trait CommentCrud extends RecordCrud[Comment] { + val table = PmSchema.commentT +} + +object CommentCrud extends CommentCrud + +// vim: set ts=2 sw=2 et: diff -r ad2fe2f9bac7 -r f7553032b302 src/main/scala/fis/pm/model/PmSchema.scala --- a/src/main/scala/fis/pm/model/PmSchema.scala Fri Apr 27 14:15:51 2012 +0200 +++ b/src/main/scala/fis/pm/model/PmSchema.scala Fri Apr 27 14:23:34 2012 +0200 @@ -57,6 +57,12 @@ Task.users.default.set(activeUsersF) + /* comment */ + val commentT = tableWithSeq[Comment] + + val commentTask = oneToManyRelation(taskT, commentT). + via((t, c) => (t.id === c.task)) + commentTask.foreignKeyDeclaration.constrainReference(onDelete cascade) } object PmSchema extends PmSchema @@ -64,7 +70,11 @@ object ProjectTasks { def apply(p: Project): Iterable[Task] = from(PmSchema.taskProject.left(p))(t => select(t) orderBy(t.deadline asc)) - +} + +object TaskComments { + def apply(t: Task): Iterable[Comment] = + from(PmSchema.commentTask.left(t))(c => select(c) orderBy(c.createdAt asc)) } // vim: set ts=2 sw=2 et: diff -r ad2fe2f9bac7 -r f7553032b302 src/main/scala/fis/pm/ui/CommentTable.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/scala/fis/pm/ui/CommentTable.scala Fri Apr 27 14:23:34 2012 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright 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.pm.ui + +import fis.pm.model.Comment +import net.liftweb.http.Templates +import net.liftweb.util.Helpers._ // CSS transforms +import scala.xml.NodeSeq + +object CommentTable { + + protected def load: NodeSeq = + Templates(List("templates-hidden", "comment")) openOr NodeSeq.Empty + + protected def build(comments: Iterable[Comment]): NodeSeq = + (".comments" #> (comments map { renderComment _ }))(load) + + protected def renderComment(c: Comment) = + ".comment-author *" #> c.createdBy.asHtml & + ".comment-body *" #> c.note.asHtml & + ".comment-footer *" #> c.createdAt.asHtml + + def apply(comments: Iterable[Comment]): NodeSeq = { + val content = comments flatMap { c => +
{c.createdBy.asHtml}
+
{c.note.asHtml}
+ + } +
{content}
+ } +} + +// vim: set ts=2 sw=2 et: diff -r ad2fe2f9bac7 -r f7553032b302 src/main/scala/fis/pm/ui/TaskSnippet.scala --- a/src/main/scala/fis/pm/ui/TaskSnippet.scala Fri Apr 27 14:15:51 2012 +0200 +++ b/src/main/scala/fis/pm/ui/TaskSnippet.scala Fri Apr 27 14:23:34 2012 +0200 @@ -36,7 +36,8 @@ private val viewPre = Menu.param[Task]("task.view", l10n("Task"), parse, encode) / prefix / * >> Title(t => i18n("Task %s", t.linkName)) >> - locTpl("entity/view") >> Snippet("panel", panel) >> Hidden + locTpl("task/view") >> Snippet("panel", panel) >> + Snippet("comments", comments) >> Hidden private val editPre = Menu.param[Task]("task.edit", l10n("Edit"), parse, encode) / prefix / * / EDIT >> @@ -48,20 +49,32 @@ Title(t => i18n("Delete task %s", t.linkName)) >> locTpl("entity/delete") >> Snippet("form", deleteF) >> Hidden - private val viewM = viewPre >> (SecNav(editPre) + deletePre).build + private val postCommentPre = Menu.param[Task]("task.post-comment", + l10n("Post comment"), parse, encode) / prefix / * / "post-comment" >> + Title(t => i18n("Post comment for task %s", t.linkName)) >> + locTpl("task/view") >> Snippet("panel", postComment) >> + Snippet("comments", comments) >> Hidden + + private val viewM = viewPre >> (SecNav(editPre) + deletePre + + postCommentPre).build private val editM = editPre >> SecNav(viewPre).build private val deleteM = deletePre >> SecNav(viewPre).build + private val postCommentM = postCommentPre >> SecNav(viewPre).build private lazy val viewLoc = viewM.toLoc private lazy val editLoc = editM.toLoc private lazy val deleteLoc = deleteM.toLoc + private lazy val postCommentLoc = postCommentM.toLoc - val menu = listM submenus(viewM, editM, deleteM) + val menu = listM submenus(viewM, editM, deleteM, postCommentM) private def cur = viewLoc.currentValue or editLoc.currentValue or - deleteLoc.currentValue + deleteLoc.currentValue or postCommentLoc.currentValue - private def panel: CssTr = "*" #> cur.map { c => ViewPanel(fields(c)) } + private def panel: CssTr = "*" #> cur.map { t => ViewPanel(fields(t)) } + + private def comments: CssTr = "*" #> cur.map { t => + CommentTable(TaskComments(t)) } object url { def view: Task => Box[String] = (viewLoc.calcHref _) andThen (Box !! _) @@ -104,6 +117,26 @@ } } + private object postComment extends HorizontalScreen with CancelButton with + SaveButton { + + private object comment extends ScreenVar[Comment](Comment.createRecord) + + addFields(() => comment.note) + + override def localSetup() { + postCommentM.toLoc.currentValue.foreach { t => comment.task(t.id) } + } + + def finish() { for { + c <- CommentCrud.save(comment) + t <- postCommentM.toLoc.currentValue + } { + S notice l10n("Comment saved.") + S redirectTo viewLoc.calcHref(t) + }} + } + } // vim: set ts=2 sw=2 et: diff -r ad2fe2f9bac7 -r f7553032b302 src/main/webapp/css/comment.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/webapp/css/comment.css Fri Apr 27 14:23:34 2012 +0200 @@ -0,0 +1,10 @@ +.comment-author:first-child { + border-top: medium none; + padding-top: 0; +} + +.comment-author { + background-position: 0 1.5em; + border-top: 1px solid #eeeeee; + padding-top: 1.5em; +} diff -r ad2fe2f9bac7 -r f7553032b302 src/main/webapp/task/view.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/webapp/task/view.html Fri Apr 27 14:23:34 2012 +0200 @@ -0,0 +1,29 @@ + + + + + Entity View + + +
+ + + +
+
+ +
+
+
+
+

+
+ +
+
+
+
+ + + + diff -r ad2fe2f9bac7 -r f7553032b302 src/main/webapp/templates-hidden/_resources.html --- a/src/main/webapp/templates-hidden/_resources.html Fri Apr 27 14:15:51 2012 +0200 +++ b/src/main/webapp/templates-hidden/_resources.html Fri Apr 27 14:23:34 2012 +0200 @@ -230,12 +230,21 @@ Deadline Responsible State [%%] + Comments + + Comment + + diff -r ad2fe2f9bac7 -r f7553032b302 src/main/webapp/templates-hidden/_resources_cs.html --- a/src/main/webapp/templates-hidden/_resources_cs.html Fri Apr 27 14:15:51 2012 +0200 +++ b/src/main/webapp/templates-hidden/_resources_cs.html Fri Apr 27 14:23:34 2012 +0200 @@ -218,11 +218,21 @@ Termín Odpovědný Stav [%%] + Komentáře Typ 1 Typ 2 + + Komentář + Komentáře + Přidat komentář + Přidat komentář k úkolu %s + Komentář uložen. + Komentář + +