Permalink
Browse files

Merge branch 'feature.issue#14_task_management'

  • Loading branch information...
2 parents 4294d59 + 5be9d2f commit 4c99b256b46e705094767405405d328db27ee7fb @henyojess committed Jan 17, 2012
@@ -0,0 +1,105 @@
+package timelog
+
+import org.springframework.dao.DataIntegrityViolationException
+
+class TaskController {
+
+ static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
+ def springSecurityService
+
+ def index() {
+ redirect(action: "list", params: params)
+ }
+
+ def list() {
+ params.max = Math.min(params.max ? params.int('max') : 10, 100)
+ [taskInstanceList: Task.list(params), taskInstanceTotal: Task.count()]
+ }
+
+ def create() {
+ [taskInstance: new Task(params)]
+ }
+
+ def save() {
+ def taskInstance = new Task(params)
+ taskInstance.createdBy = springSecurityService.getPrincipal().username
+ if (!taskInstance.save(flush: true)) {
+ render(view: "create", model: [taskInstance: taskInstance])
+ return
+ }
+
+ flash.message = message(code: 'default.created.message', args: [message(code: 'task.label', default: 'Task'), taskInstance.id])
+ redirect(action: "show", id: taskInstance.id)
+ }
+
+ def show() {
+ def taskInstance = Task.get(params.id)
+ if (!taskInstance) {
+ flash.message = message(code: 'default.not.found.message', args: [message(code: 'task.label', default: 'Task'), params.id])
+ redirect(action: "list")
+ return
+ }
+
+ [taskInstance: taskInstance]
+ }
+
+ def edit() {
+ def taskInstance = Task.get(params.id)
+ if (!taskInstance) {
+ flash.message = message(code: 'default.not.found.message', args: [message(code: 'task.label', default: 'Task'), params.id])
+ redirect(action: "list")
+ return
+ }
+
+ [taskInstance: taskInstance]
+ }
+
+ def update() {
+ def taskInstance = Task.get(params.id)
+ if (!taskInstance) {
+ flash.message = message(code: 'default.not.found.message', args: [message(code: 'task.label', default: 'Task'), params.id])
+ redirect(action: "list")
+ return
+ }
+
+ if (params.version) {
+ def version = params.version.toLong()
+ if (taskInstance.version > version) {
+ taskInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
+ [message(code: 'task.label', default: 'Task')] as Object[],
+ "Another user has updated this Task while you were editing")
+ render(view: "edit", model: [taskInstance: taskInstance])
+ return
+ }
+ }
+
+ taskInstance.properties = params
+ taskInstance.updatedBy = springSecurityService.getPrincipal().username
+ if (!taskInstance.save(flush: true)) {
+ render(view: "edit", model: [taskInstance: taskInstance])
+ return
+ }
+
+ flash.message = message(code: 'default.updated.message', args: [message(code: 'task.label', default: 'Task'), taskInstance.id])
+ redirect(action: "show", id: taskInstance.id)
+ }
+
+ def delete() {
+ def taskInstance = Task.get(params.id)
+ if (!taskInstance) {
+ flash.message = message(code: 'default.not.found.message', args: [message(code: 'task.label', default: 'Task'), params.id])
+ redirect(action: "list")
+ return
+ }
+
+ try {
+ taskInstance.delete(flush: true)
+ flash.message = message(code: 'default.deleted.message', args: [message(code: 'task.label', default: 'Task'), params.id])
+ redirect(action: "list")
+ }
+ catch (DataIntegrityViolationException e) {
+ flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'task.label', default: 'Task'), params.id])
+ redirect(action: "show", id: params.id)
+ }
+ }
+}
@@ -13,11 +13,13 @@ class Story {
static belongsTo = Project
+ static hasMany = [ tasks: Task ]
+
static constraints = {
description blank:false
releaseTarget blank:false
status blank:false
createdBy blank:false
- updatedBy nullable:true,blank:false
+ updatedBy nullable:true,blank:false
}
}
@@ -0,0 +1,26 @@
+package timelog
+
+class Task {
+
+ String description
+ String status = 'Incomplete'
+ Integer estimate
+ Story story
+
+ String createdBy
+ String updatedBy
+ Date dateCreated
+ Date lastUpdated
+
+ static belongsTo = Story
+
+ static hasMany = [ timeEntries:TimeEntry ]
+
+ static constraints = {
+ description blank:false
+ status blank:false
+ estimate nullable:true, min:1 ,max:16
+ createdBy blank:false
+ updatedBy nullable:true,blank:false
+ }
+}
@@ -9,13 +9,17 @@ class TimeEntry {
String updatedBy
Date dateCreated
Date lastUpdated
+ Task task
+
+ static belongsTo = Task
static constraints = {
description blank:false
duration nullable:false, min:1
entryDate nullable:false
createdBy blank:false
updatedBy nullable:true
+ task nullable:true
}
static Date today(){
@@ -0,0 +1,36 @@
+<%@ page import="timelog.Task" %>
+
+<div class="fieldcontain ${hasErrors(bean: taskInstance, field: 'story', 'error')} required">
+ <label for="story">
+ <g:message code="task.story.label" default="Story" />
+ <span class="required-indicator">*</span>
+ </label>
+ <g:select id="story" name="story.id" from="${timelog.Story.list()}"
+ optionKey="id" optionValue="description" required="" value="${taskInstance?.story?.id}" class="many-to-one"/>
+</div>
+
+
+<div class="fieldcontain ${hasErrors(bean: taskInstance, field: 'description', 'error')} required">
+ <label for="description">
+ <g:message code="task.description.label" default="Description" />
+ <span class="required-indicator">*</span>
+ </label>
+ <g:textField name="description" required="" value="${taskInstance?.description}"/>
+</div>
+
+<div class="fieldcontain ${hasErrors(bean: taskInstance, field: 'status', 'error')} required">
+ <label for="status">
+ <g:message code="task.status.label" default="Status" />
+ <span class="required-indicator">*</span>
+ </label>
+ <g:textField name="status" required="" value="${taskInstance?.status}"/>
+</div>
+
+<div class="fieldcontain ${hasErrors(bean: taskInstance, field: 'estimate', 'error')} required">
+ <label for="estimate">
+ <g:message code="task.estimate.label" default="Estimate" />
+ <span class="required-indicator">*</span>
+ </label>
+ <g:field type="number" name="estimate" min="1" max="16" required="" value="${fieldValue(bean: taskInstance, field: 'estimate')}"/>
+</div>
+
@@ -0,0 +1,39 @@
+<%@ page import="timelog.Task" %>
+<!doctype html>
+<html>
+ <head>
+ <meta name="layout" content="main">
+ <g:set var="entityName" value="${message(code: 'task.label', default: 'Task')}" />
+ <title><g:message code="default.create.label" args="[entityName]" /></title>
+ </head>
+ <body>
+ <a href="#create-task" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
+ <div class="nav" role="navigation">
+ <ul>
+ <li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
+ <li><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></li>
+ </ul>
+ </div>
+ <div id="create-task" class="content scaffold-create" role="main">
+ <h1><g:message code="default.create.label" args="[entityName]" /></h1>
+ <g:if test="${flash.message}">
+ <div class="message" role="status">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${taskInstance}">
+ <ul class="errors" role="alert">
+ <g:eachError bean="${taskInstance}" var="error">
+ <li <g:if test="${error in org.springframework.validation.FieldError}">data-field-id="${error.field}"</g:if>><g:message error="${error}"/></li>
+ </g:eachError>
+ </ul>
+ </g:hasErrors>
+ <g:form action="save" >
+ <fieldset class="form">
+ <g:render template="form"/>
+ </fieldset>
+ <fieldset class="buttons">
+ <g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
+ </fieldset>
+ </g:form>
+ </div>
+ </body>
+</html>
@@ -0,0 +1,43 @@
+<%@ page import="timelog.Task" %>
+<!doctype html>
+<html>
+ <head>
+ <meta name="layout" content="main">
+ <g:set var="entityName" value="${message(code: 'task.label', default: 'Task')}" />
+ <title><g:message code="default.edit.label" args="[entityName]" /></title>
+ </head>
+ <body>
+ <a href="#edit-task" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
+ <div class="nav" role="navigation">
+ <ul>
+ <li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
+ <li><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></li>
+ <li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
+ </ul>
+ </div>
+ <div id="edit-task" class="content scaffold-edit" role="main">
+ <h1><g:message code="default.edit.label" args="[entityName]" /></h1>
+ <g:if test="${flash.message}">
+ <div class="message" role="status">${flash.message}</div>
+ </g:if>
+ <g:hasErrors bean="${taskInstance}">
+ <ul class="errors" role="alert">
+ <g:eachError bean="${taskInstance}" var="error">
+ <li <g:if test="${error in org.springframework.validation.FieldError}">data-field-id="${error.field}"</g:if>><g:message error="${error}"/></li>
+ </g:eachError>
+ </ul>
+ </g:hasErrors>
+ <g:form method="post" >
+ <g:hiddenField name="id" value="${taskInstance?.id}" />
+ <g:hiddenField name="version" value="${taskInstance?.version}" />
+ <fieldset class="form">
+ <g:render template="form"/>
+ </fieldset>
+ <fieldset class="buttons">
+ <g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" />
+ <g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" formnovalidate="" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
+ </fieldset>
+ </g:form>
+ </div>
+ </body>
+</html>
@@ -0,0 +1,66 @@
+
+<%@ page import="timelog.Task" %>
+<!doctype html>
+<html>
+ <head>
+ <meta name="layout" content="main">
+ <g:set var="entityName" value="${message(code: 'task.label', default: 'Task')}" />
+ <title><g:message code="default.list.label" args="[entityName]" /></title>
+ </head>
+ <body>
+ <a href="#list-task" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
+ <div class="nav" role="navigation">
+ <ul>
+ <li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
+ <li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
+ </ul>
+ </div>
+ <div id="list-task" class="content scaffold-list" role="main">
+ <h1><g:message code="default.list.label" args="[entityName]" /></h1>
+ <g:if test="${flash.message}">
+ <div class="message" role="status">${flash.message}</div>
+ </g:if>
+ <table>
+ <thead>
+ <tr>
+
+ <g:sortableColumn property="description" title="${message(code: 'task.description.label', default: 'Description')}" />
+
+ <g:sortableColumn property="status" title="${message(code: 'task.status.label', default: 'Status')}" />
+
+ <g:sortableColumn property="estimate" title="${message(code: 'task.estimate.label', default: 'Estimate')}" />
+
+ <g:sortableColumn property="createdBy" title="${message(code: 'task.createdBy.label', default: 'Created By')}" />
+
+ <g:sortableColumn property="updatedBy" title="${message(code: 'task.updatedBy.label', default: 'Updated By')}" />
+
+ <g:sortableColumn property="dateCreated" title="${message(code: 'task.dateCreated.label', default: 'Date Created')}" />
+
+ </tr>
+ </thead>
+ <tbody>
+ <g:each in="${taskInstanceList}" status="i" var="taskInstance">
+ <tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
+
+ <td><g:link action="show" id="${taskInstance.id}">${fieldValue(bean: taskInstance, field: "description")}</g:link></td>
+
+ <td>${fieldValue(bean: taskInstance, field: "status")}</td>
+
+ <td>${fieldValue(bean: taskInstance, field: "estimate")}</td>
+
+ <td>${fieldValue(bean: taskInstance, field: "createdBy")}</td>
+
+ <td>${fieldValue(bean: taskInstance, field: "updatedBy")}</td>
+
+ <td><g:formatDate date="${taskInstance.dateCreated}" /></td>
+
+ </tr>
+ </g:each>
+ </tbody>
+ </table>
+ <div class="pagination">
+ <g:paginate total="${taskInstanceTotal}" />
+ </div>
+ </div>
+ </body>
+</html>
Oops, something went wrong.

0 comments on commit 4c99b25

Please sign in to comment.