TimeLine events support

Directive added to render different templates depending on event_type.

Change-Id: I41496d08ef99afe230b20ddb1c1e12a208f0415e
This commit is contained in:
Nikita Konovalov
2014-04-17 23:10:40 +04:00
parent fa26d4961d
commit 3ba9f7e1eb
15 changed files with 180 additions and 21 deletions

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2014 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.
*/
/**
* The angular resource abstraction that allows us to access discussions that
* are surrounding stories.
*
* @see storyboardApiSignature
*/
angular.module('sb.services').factory('TimelineEvent',
function ($resource, storyboardApiBase, storyboardApiSignature) {
'use strict';
return $resource(storyboardApiBase + '/stories/:story_id/events/:id',
{
id: '@id',
story_id: '@story_id'
},
storyboardApiSignature);
});

View File

@@ -18,7 +18,8 @@
* Controller used for the comments section on the story detail page.
*/
angular.module('sb.story').controller('StoryDiscussionController',
function ($log, $scope, $state, $stateParams, Project, Comment) {
function ($log, $scope, $state, $stateParams, Project, Comment,
TimelineEvent) {
'use strict';
// Parse the ID
@@ -29,7 +30,7 @@ angular.module('sb.story').controller('StoryDiscussionController',
/**
* The story we're manipulating right now.
*/
$scope.comments = Comment.query({story_id: id});
$scope.events = TimelineEvent.query({story_id: id});
/**
* The new comment backing the input form.
@@ -77,8 +78,8 @@ angular.module('sb.story').controller('StoryDiscussionController',
// Author ID will be automatically attached by the service, so
// don't inject it into the conversation until it comes back.
$scope.newComment.$create(
function (comment) {
$scope.comments.push(comment);
function (event) {
$scope.events.push(event);
$scope.newComment = new Comment({story_id: id});
resetSavingFlag();
},

View File

@@ -18,10 +18,16 @@
* Controller used for the comments section on the story detail page.
*/
angular.module('sb.story').controller('StoryDiscussionItemController',
function ($scope, User) {
function ($scope, $log, User) {
'use strict';
$scope.author = User.get({
id: $scope.comment.author_id
id: $scope.event.author_id
});
try {
$scope.event_info = JSON.parse($scope.event.event_info);
} catch (error) {
$log.warn(error);
}
});

View File

@@ -0,0 +1,6 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{ author.full_name }} has created this story.
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,6 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{ author.full_name }} has updated this story.
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,7 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{author.full_name}} has updated assignee for task {{ event_info.task_title }}:
{{ event_info.old_assignee_fullname }} ==> {{ event_info.new_assignee_fullname }}
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,6 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{ author.full_name }} has created a task {{ event_info.task_title }}
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,6 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{ author.full_name }} has deleted a task {{ event_info.task_title }}
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,6 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{ author.full_name }} has updated {{ event_info.task_title }}
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,7 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{author.full_name}} has updated a task {{ event_info.task_title }} status:
{{ event_info.old_status }} ==> {{ event_info.new_status }}
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>

View File

@@ -0,0 +1,35 @@
<div ng-switch="event_type">
<div ng-switch-when="story_created">
<div ng-include src="'app/templates/story/comments/story_created.html'"></div>
</div>
<div ng-switch-when="story_details_updated">
<div ng-include src="'app/templates/story/comments/story_details_updated.html'"></div>
</div>
<div ng-switch-when="task_assignee_changed">
<div ng-include src="'app/templates/story/comments/task_assignee_changed.html'"></div>
</div>
<div ng-switch-when="task_created">
<div ng-include src="'app/templates/story/comments/task_created.html'"></div>
</div>
<div ng-switch-when="task_deleted">
<div ng-include src="'app/templates/story/comments/task_deleted.html'"></div>
</div>
<div ng-switch-when="task_details_changed">
<div ng-include src="'app/templates/story/comments/task_details_changed.html'"></div>
</div>
<div ng-switch-when="task_status_changed">
<div ng-include src="'app/templates/story/comments/task_status_changed.html'"></div>
</div>
<div ng-switch-when="user_comment">
<div ng-include src="'app/templates/story/comments/user_comment.html'"></div>
</div>
<div ng-switch-default>
<div class="discussion-comment">
<p class="discussion-comment-author">
Event of unknown type has occurred.
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
<div class="discussion-comment">
<p class="discussion-comment-author">
{{ author.full_name }}
<span class="pull-right">{{event.created_at | date: 'medium'}}</span>
</p>
<p ng-show="event.comment.content"
class="honor-carriage-return">{{event.comment.content}}
</p>
<p><em ng-hide="event.comment.content"
class="text-muted">
The author left a blank comment.
</em></p>
</div>

View File

@@ -185,27 +185,16 @@
<!-- Template for the task list -->
<script type="text/ng-template" id="/inline/discussion.html">
<div ng-controller="StoryDiscussionController">
<h4>Discussion</h4>
<h4>Events timeline</h4>
<div class="discussion">
<div class="alert alert-warning"
ng-show="comments.length == 0">
The discussion hasn't started yet
</div>
<div ng-repeat="comment in comments"
ng-controller="StoryDiscussionItemController"
class="discussion-comment">
<p class="discussion-comment-author">
{{author.full_name}}
</p>
<p ng-show="comment.content"
class="honor-carriage-return">{{comment.content}}</p>
<p><em ng-hide="comment.content"
class="text-muted">
The author left a blank comment.
</em></p>
<div ng-repeat="event in events"
ng-controller="StoryDiscussionItemController">
<timeline-event tl_event={{event}}/>
</div>
<form class="discussion-comment-form comment"

View File

@@ -0,0 +1,35 @@
/*
* Copyright (c) 2014 Mirantis Inc.
*
* 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.
*/
angular.module('sb.util').directive('timelineEvent', function($log) {
'use strict';
return {
restrict: 'E',
replace: true,
link: function(scope, element, attrs) {
var tlEvent;
try {
tlEvent = JSON.parse(attrs.tlEvent);
scope.event_type = tlEvent.event_type;
} catch (error) {
$log.warn(error);
scope.event_type = 'unknown';
}
},
templateUrl: 'app/templates/story/comments/template_switch.html'
};
});

View File

@@ -38,6 +38,7 @@
> p {
padding: @table-cell-padding;
padding-bottom: 0px;
}
}