Story detail view cleanup

This commit collapses the multi-column view into a much more compact
vertical layout, and with the added screen realestate adds more
obvious edit controls for tasks.

- Collapsed story detail view into a single column.
- Added better edit toggle controls for the story and task edit forms.
- Pulled task edit form out into its own custom directive so we can
use it in multiple places.
- Added disabled controls for author editing, since filtering
thousands of users needs to be implemented on the backend first,
and the assignee_id patch hasn't landed yet.

Change-Id: I92b05ca7ef4b2bb4d0cc536eb2acf278249e2fe6
This commit is contained in:
Michael Krotscheck 2014-04-18 10:09:23 -07:00
parent 090dd8b28e
commit 0c1d28d251
5 changed files with 236 additions and 127 deletions

View File

@ -18,7 +18,7 @@
* Controller that provides methods that allow editing of a story.
*/
angular.module('sb.story').controller('StoryTaskListController',
function ($log, $scope, $state, $stateParams, Task, Project) {
function ($log, $scope, $state, $stateParams, Task) {
'use strict';
// Parse the ID
@ -44,11 +44,6 @@ angular.module('sb.story').controller('StoryTaskListController',
*/
$scope.newTask = new Task({ story_id: id });
/**
* Projects for the new task form
*/
$scope.projects = Project.query();
/**
* UI flag for when we're initially loading the view.
*
@ -87,8 +82,8 @@ angular.module('sb.story').controller('StoryTaskListController',
* Adds a task.
*/
$scope.addTask = function () {
$scope.newTask.$save(function () {
$scope.loadTasks();
$scope.newTask.$save(function (savedTask) {
$scope.tasks.push(savedTask);
$scope.newTask = new Task({story_id: id});
});
};

View File

@ -18,10 +18,11 @@
* Controller for our story list.
*/
angular.module('sb.story').controller('StoryTaskListItemController',
function ($scope, $state, $modal, Project, Session, Task) {
function ($scope, $state, $modal, Project, Session, Task, User) {
'use strict';
var projectId = $scope.task.project_id || null;
var assigneeId = $scope.task.assignee_id || null;
if (!!projectId) {
Project.get({id: projectId},
@ -32,6 +33,16 @@ angular.module('sb.story').controller('StoryTaskListItemController',
});
}
if (!!assigneeId) {
User.get({id: assigneeId},
function (assignee) {
$scope.assignee = assignee;
}, function () {
$scope.assignee = null;
});
}
/**
* Updates this task's status
*/
@ -89,7 +100,7 @@ angular.module('sb.story').controller('StoryTaskListItemController',
};
/**
* Removes this task
* Updates the task list.
*/
$scope.updateTask = function () {
$scope.task.$update(function () {

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
*
* 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.
*/
/**
* This directive encapsulates our task edit form.
*/
angular.module('sb.story').directive('taskEditForm',
function () {
'use strict';
return {
restrict: 'E',
templateUrl: 'app/templates/story/task_edit_form.html',
scope: {
task: '=',
onButtonClick: '&',
buttonLabel: '@'
},
controller: function ($scope, Project) {
$scope.projects = Project.query();
}
};
});

View File

@ -16,7 +16,7 @@
<div class="container" ng-controller="StoryDetailController">
<div class="row">
<div class="col-md-8 col-xs-12">
<div class="col-xs-12">
<div ng-include
src="'/inline/story_detail.html'"
ng-hide="showEditForm">
@ -25,18 +25,10 @@
src="'/inline/story_detail_form.html'"
ng-show="showEditForm">
</div>
<div ng-include src="'/inline/task_list.html'"></div>
<hr/>
<div ng-include src="'/inline/discussion.html'"></div>
</div>
<div class="col-md-4 col-xs-12">
<h1 class="hidden-xs hidden-sm no-border text-right">
<!-- Spacer -->
&nbsp;
</h1>
<div ng-include src="'/inline/metadata.html'"></div>
<hr/>
<div ng-include src="'/inline/task_list.html'"></div>
</div>
</div>
</div>
@ -51,6 +43,7 @@
No title
</em>
</h1>
<div ng-include src="'/inline/metadata.html'"></div>
<p ng-click="toggleEditMode()" class="editable">
<span ng-show="story.description"
class="honor-carriage-return">{{story.description}}
@ -67,11 +60,11 @@
<form name="storyForm">
<div class="form-group">
<textarea type="text"
class="form-control context-edit h1"
ng-model="story.title"
required
ng-disabled="isUpdating"
placeholder="Story Title">
class="form-control context-edit h1"
ng-model="story.title"
required
ng-disabled="isUpdating"
placeholder="Story Title">
</textarea>
</div>
<div class="form-group">
@ -113,80 +106,52 @@
<!-- Template for the task list -->
<script type="text/ng-template" id="/inline/task_list.html">
<div ng-controller="StoryTaskListController">
<button type="button"
ng-click="showAddTaskForm = !showAddTaskForm"
ng-show="isLoggedIn"
class="pull-right btn btn-default btn-sm">
<i class="fa fa-plus"
ng-hide="showAddTaskForm"></i>
<i class="fa fa-minus"
ng-show="showAddTaskForm"></i>
</button>
<h4>Tasks</h4>
<div class="well" ng-show="showAddTaskForm">
<form role="form" name="taskForm">
<div class="form-group row">
<label for="title" class="col-sm-2 control-label">
Task Title:
</label>
<div class="col-sm-10">
<input id="title"
type="text"
class="form-control"
ng-model="newTask.title"
required
placeholder="Task Title">
</div>
</div>
<div class="form-group row">
<label for="project" class="col-sm-2 control-label">
Task Project:
</label>
<div class="col-sm-10">
<select ng-model="newTask.project_id"
id="project"
name="project"
class="form-control"
required
ng-options="p.id as p.name for p in projects"/>
</div>
</div>
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default"
ng-click="addTask()"
ng-disabled="!taskForm.$valid">
<table class="table table-striped"
ng-controller="StoryTaskListController">
<thead>
<tr>
<td colspan="3"><strong>Tasks</strong></td>
<td colspan="3" class="text-right">
<small>
<a href=""
ng-click="showAddTaskForm = !showAddTaskForm"
ng-show="isLoggedIn">
<i class="fa fa-plus"></i>
Add task
</button>
</div>
</div>
</form>
</div>
<table class="table table-striped">
<tbody>
<tr ng-repeat="task in tasks"
ng-controller="StoryTaskListItemController">
<td ng-hide="showTaskEditForm"
class="editable"
ng-include
ng-click="toggleEditForm()"
src="'/inline/task_list_item.html'">
</td>
<td ng-show="showTaskEditForm"
ng-include
src="'/inline/task_list_item_form.html'">
</a>
</small>
</td>
</tr>
</tbody>
</table>
</div>
</thead>
<tbody>
<tr ng-repeat="task in tasks"
ng-include
src="'/inline/task_list_item.html'"
ng-controller="StoryTaskListItemController">
</tr>
<tr ng-show="tasks.length == 0 && !showAddTaskForm">
<td colspan="6">
<p class="text-muted text-center">
<em>This story has no tasks.</em>
</p>
</td>
</tr>
</tbody>
<tfoot ng-show="showAddTaskForm">
<tr>
<td></td>
<td colspan="3">
<task-edit-form
task="newTask"
button-label="Add Task"
on-button-click="addTask()"
/>
</td>
<td colspan="2"></td>
</tr>
</tfoot>
</table>
</script>
@ -246,44 +211,109 @@
<!-- Template for an item in the task list -->
<script type="text/ng-template" id="/inline/task_list_item.html">
<div class="pull-right">
<td ng-show="isLoggedIn">
<a href=""
ng-click="showTaskEditForm = true"
ng-hide="showTaskEditForm">
<i class="fa fa-caret-right fa-lg"></i>
</a>
<a href=""
ng-click="showTaskEditForm = false"
ng-show="showTaskEditForm">
<i class="fa fa-caret-down fa-lg"></i>
</a>
</td>
<td ng-hide="showTaskEditForm">
<a href=""
ng-show="isLoggedIn"
ng-click="showTaskEditForm = true">
{{task.title}}
</a>
<span ng-hide="isLoggedIn">
{{task.title}}
</span>
</td>
<td ng-hide="showTaskEditForm">
<a href=""
ng-click="showTaskEditForm = true"
ng-show="isLoggedIn">
<span ng-show="project">
{{project.name}}
</span>
<em class="text-muted" ng-hide="project">
Project not found
</em>
</a>
<span ng-hide="isLoggedIn">
<span ng-show="project">
{{project.name}}
</span>
<em class="text-muted" ng-hide="project">
Project not found
</em>
</span>
</td>
<td ng-hide="showTaskEditForm">
<span ng-show="assignee">
{{assignee.full_name}}
</span>
<em class="text-muted" ng-hide="assignee">
Not assigned
</em>
</td>
<td ng-show="showTaskEditForm"
colspan="3">
<task-edit-form
task="task"
on-button-click="updateTask()"
button-label="Update"
/>
</td>
<td class="text-right">
<task-status-dropdown
editable="{{isLoggedIn}}"
on-change="updateStatus(status)"
status="{{task.status}}"
/>
</div>
<p>
<strong ng-show="project" class="text-primary">
{{project.name}}
</strong>
<em class="text-muted" ng-hide="project">
Project not found
</em>
</p>
<p>
{{task.title}}
</p>
</td>
<td class="text-right">
<a ng-show="isLoggedIn"
ng-click="removeTask()">
<i class="fa fa-times fa-lg"></i>
</a>
</td>
</script>
<!-- Template for an item in the task list -->
<script type="text/ng-template" id="/inline/task_list_item_form.html">
<form name="taskForm">
<div class="form-group">
<select ng-model="task.project_id"
<label for="title">Task Summary:</label>
<textarea
name="title"
ng-model="task.title"
required
maxlength="255"
placeholder="Describe the specifics of your task here"
class="form-control input-sm">
</textarea>
</div>
<div class="form-group">
<label for="project">Affected Project:</label>
<select name="project"
ng-model="task.project_id"
class="form-control input-sm"
required
placeholder="Project"
ng-options="p.id as p.name for p in projects"/>
</div>
<div class="form-group">
<textarea
ng-model="task.title"
required
placeholder="Describe the specifics of your task here"
class="form-control input-sm">
</textarea>
<label for="assignee">Assigned To:</label>
<input type="text"
ng-model="assignee.full_name"
disabled
placeholder="Not yet implemented"
class="form-control input-sm"/>
</div>
<div class="form-group">
<div class="clearfix">
@ -295,19 +325,9 @@
class="btn btn-primary"
ng-click="updateTask()"
ng-disabled="!taskForm.$valid">
Save
</button>
<button type="button"
class="btn btn-default"
ng-click="cancelTask()">
Cancel
Update
</button>
</div>
<button type="button"
class="btn btn-link"
ng-click="removeTask()">
Remove this task
</button>
</div>
</div>
</form>

View File

@ -0,0 +1,46 @@
<form name="taskForm">
<div class="form-group">
<label for="title">Task Summary:</label>
<textarea
name="title"
ng-model="task.title"
required
maxlength="255"
placeholder="Describe the specifics of your task here"
class="form-control input-sm">
</textarea>
</div>
<div class="form-group">
<label for="project">Affected Project:</label>
<select name="project"
ng-model="task.project_id"
class="form-control input-sm"
required
placeholder="Project"
ng-options="p.id as p.name for p in projects"/>
</div>
<div class="form-group">
<label for="assignee">Assigned To:</label>
<input type="text"
ng-model="assignee.full_name"
disabled
placeholder="Not yet implemented"
class="form-control input-sm"/>
</div>
<div class="form-group">
<div class="clearfix">
<div class="pull-right">
<div class="btn" ng-show="isUpdating">
<i class="fa fa-spinner fa-lg fa-spin"></i>
</div>
<button type="button"
class="btn btn-primary"
ng-click="onButtonClick({})"
ng-disabled="!taskForm.$valid">
{{buttonLabel}}
</button>
</div>
</div>
</div>
</form>
</form>