Display a modal when a card is clicked on
This modal shows some information about the task/story the card represents, and also allows it all to be edited. This includes changing task assignee and assigning due dates to the task. Only one due date can be displayed on a card at any given time. Change-Id: I69866756e4b6b569e7f88cf41bb00c45ca5dedb9
This commit is contained in:
parent
e8b8c9fe3c
commit
55712fc403
@ -378,6 +378,28 @@ angular.module('sb.board').controller('BoardDetailController',
|
||||
}
|
||||
};
|
||||
|
||||
$scope.showCardDetail = function(card) {
|
||||
var modalInstance = $modal.open({
|
||||
templateUrl: 'app/boards/template/card_details.html',
|
||||
controller: 'CardDetailController',
|
||||
resolve: {
|
||||
card: function() {
|
||||
return card;
|
||||
},
|
||||
board: function() {
|
||||
return $scope.board;
|
||||
},
|
||||
permissions: function() {
|
||||
return $scope.permissions;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modalInstance.result.finally(function() {
|
||||
loadBoard();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Config for the lanes sortable.
|
||||
*/
|
||||
|
256
src/app/boards/controller/card_detail_controller.js
Normal file
256
src/app/boards/controller/card_detail_controller.js
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Codethink Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Controller for the card detail modal.
|
||||
*/
|
||||
angular.module('sb.board').controller('CardDetailController',
|
||||
function ($scope, card, board, permissions, Story, Task, DueDate,
|
||||
Worklist, $document, $timeout, $modalInstance, $modal) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Story/Task title
|
||||
*/
|
||||
$scope.modifications = {
|
||||
title: '',
|
||||
description: ''
|
||||
};
|
||||
$scope.toggleEditTitle = function() {
|
||||
if (!(permissions.moveCards || permissions.editBoard)) {
|
||||
return false;
|
||||
}
|
||||
if (!$scope.editingTitle) {
|
||||
if (card.item_type === 'story') {
|
||||
$scope.modifications.title = card.story.title;
|
||||
} else if (card.item_type === 'task') {
|
||||
$scope.modifications.title = card.task.title;
|
||||
}
|
||||
}
|
||||
$scope.editingTitle = !$scope.editingTitle;
|
||||
};
|
||||
|
||||
$scope.editTitle = function() {
|
||||
var params = {};
|
||||
if (card.item_type === 'story') {
|
||||
params = {
|
||||
id: card.story.id,
|
||||
title: $scope.modifications.title
|
||||
};
|
||||
Story.update(params, function(updated) {
|
||||
$scope.toggleEditTitle();
|
||||
card.story.title = updated.title;
|
||||
});
|
||||
} else if (card.item_type === 'task') {
|
||||
params = {
|
||||
id: card.task.id,
|
||||
title: $scope.modifications.title
|
||||
};
|
||||
Task.update(params, function(updated) {
|
||||
$scope.toggleEditTitle();
|
||||
card.task.title = updated.title;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Story description
|
||||
*/
|
||||
$scope.toggleEditDescription = function() {
|
||||
if (!(permissions.moveCards || permissions.editBoard)) {
|
||||
return false;
|
||||
}
|
||||
if (!$scope.editingTitle) {
|
||||
$scope.modifications.description = $scope.story.description;
|
||||
}
|
||||
$scope.editingDescription = !$scope.editingDescription;
|
||||
};
|
||||
|
||||
$scope.editStoryDescription = function() {
|
||||
var params = {
|
||||
id: $scope.story.id,
|
||||
description: $scope.modifications.description
|
||||
};
|
||||
Story.update(params, function(updated) {
|
||||
$scope.toggleEditDescription();
|
||||
$scope.story.description = updated.description;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Due dates
|
||||
*/
|
||||
$scope.noDate = {
|
||||
id: -1,
|
||||
date: null
|
||||
};
|
||||
|
||||
$scope.getRelevantDueDates = function() {
|
||||
$scope.relevantDates = [];
|
||||
angular.forEach(board.due_dates, function(date) {
|
||||
if (date.assignable) {
|
||||
$scope.relevantDates.push(date);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.toggleEditDueDate = function() {
|
||||
if (permissions.moveCards || permissions.editBoard) {
|
||||
$scope.editingDueDate = !$scope.editingDueDate;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleDueDateDropdown = function() {
|
||||
var dropdown = $document[0].getElementById('due-dates-dropdown');
|
||||
var button = dropdown.getElementsByTagName('button')[0];
|
||||
$timeout(function() {
|
||||
button.click();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
function cardHasDate(date) {
|
||||
for (var i = 0; i < card[card.item_type].due_dates.length; i++) {
|
||||
if (card[card.item_type].due_dates[i] === date.id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function assignDueDate(date) {
|
||||
if (card.item_type === 'task') {
|
||||
date.tasks.push(card.task);
|
||||
} else if (card.item_type === 'story') {
|
||||
date.stories.push(card.story);
|
||||
}
|
||||
var params = {
|
||||
id: date.id,
|
||||
tasks: date.tasks,
|
||||
stories: date.stories
|
||||
};
|
||||
DueDate.update(params).$promise.then(function(updated) {
|
||||
if (card.item_type === 'task') {
|
||||
card.task.due_dates.push(updated.id);
|
||||
$scope.getRelevantDueDates(card.task.due_dates);
|
||||
} else if (card.item_type === 'story') {
|
||||
card.story.due_dates.push(updated.id);
|
||||
$scope.getRelevantDueDates(card.story.due_dates);
|
||||
}
|
||||
$scope.assigningDueDate = false;
|
||||
});
|
||||
}
|
||||
|
||||
$scope.setDisplayDate = function(date) {
|
||||
if (!cardHasDate(date) && date.id !== -1) {
|
||||
assignDueDate(date);
|
||||
}
|
||||
card.resolved_due_date = date;
|
||||
var params = {
|
||||
id: card.list_id,
|
||||
item_id: card.id,
|
||||
list_position: card.list_position,
|
||||
display_due_date: date.id
|
||||
};
|
||||
Worklist.ItemsController.update(params, function() {
|
||||
$scope.editingDueDate = false;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.validDueDate = function(dueDate) {
|
||||
return dueDate && !(dueDate === $scope.noDate);
|
||||
};
|
||||
|
||||
/**
|
||||
* Task assignee
|
||||
*/
|
||||
$scope.toggleAssigneeTypeahead = function() {
|
||||
var typeahead = $document[0].getElementById('assignee');
|
||||
var assignLink = typeahead.getElementsByTagName('a')[0];
|
||||
$timeout(function() {
|
||||
assignLink.click();
|
||||
}, 0);
|
||||
};
|
||||
|
||||
$scope.toggleEditAssignee = function() {
|
||||
$scope.editingAssignee = !$scope.editingAssignee;
|
||||
};
|
||||
|
||||
$scope.updateTask = function(task) {
|
||||
var params = {
|
||||
id: task.id,
|
||||
assignee_id: task.assignee_id
|
||||
};
|
||||
Task.update(params, function() {
|
||||
$scope.editingAssignee = false;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Other
|
||||
*/
|
||||
$scope.deleteCard = function() {
|
||||
Worklist.ItemsController.delete({
|
||||
id: $scope.card.list_id,
|
||||
item_id: $scope.card.id
|
||||
}, function() {
|
||||
$modalInstance.close('deleted');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.close = function() {
|
||||
$modalInstance.close('closed');
|
||||
};
|
||||
|
||||
|
||||
$scope.newDueDate = function() {
|
||||
var modalInstance = $modal.open({
|
||||
templateUrl: 'app/due_dates/template/new.html',
|
||||
controller: 'DueDateNewController',
|
||||
resolve: {
|
||||
board: function() {
|
||||
return board;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modalInstance.result.then(function(dueDate) {
|
||||
if (dueDate.hasOwnProperty('date')) {
|
||||
board.due_dates.push(dueDate);
|
||||
}
|
||||
|
||||
$scope.getRelevantDueDates();
|
||||
$scope.setDisplayDate(dueDate);
|
||||
});
|
||||
};
|
||||
|
||||
if (card.item_type === 'task') {
|
||||
$scope.story = Story.get({id: card.task.story_id});
|
||||
} else if (card.item_type === 'story') {
|
||||
$scope.story = card.story;
|
||||
}
|
||||
$scope.getRelevantDueDates();
|
||||
|
||||
$scope.card = card;
|
||||
$scope.board = board;
|
||||
$scope.permissions = permissions;
|
||||
$scope.showDescription = true;
|
||||
$scope.assigningDueDate = false;
|
||||
$scope.editingDueDate = false;
|
||||
$scope.editingDescription = false;
|
||||
$scope.editingAssignee = false;
|
||||
}
|
||||
);
|
@ -20,7 +20,8 @@
|
||||
ng-class="{'kanban-card-due': isDue(item), 'kanban-card-late': isLate(item)}"
|
||||
as-sortable-item
|
||||
ng-repeat="item in lane.worklist.items"
|
||||
ng-switch="item.item_type">
|
||||
ng-switch="item.item_type"
|
||||
ng-click="showCardDetail(item)">
|
||||
<div as-sortable-item-handle ng-switch-when="story">
|
||||
<div class="row">
|
||||
<div class="col-xs-1">
|
||||
@ -31,7 +32,7 @@
|
||||
ng-click="removeCard(lane.worklist, item); $event.stopPropagation();">
|
||||
×
|
||||
</button>
|
||||
<a href="#!/story/{{item.story.id}}">
|
||||
<a>
|
||||
{{item.story.title}}
|
||||
</a>
|
||||
</div>
|
||||
@ -60,7 +61,7 @@
|
||||
ng-click="removeCard(lane.worklist, item); $event.stopPropagation()">
|
||||
×
|
||||
</button>
|
||||
<a href="#!/story/{{item.task.story_id}}">
|
||||
<a>
|
||||
{{item.task.title}}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -17,14 +17,15 @@
|
||||
<div class="kanban-card-readonly"
|
||||
ng-class="{'kanban-card-due': isDue(item), 'kanban-card-late': isLate(item)}"
|
||||
ng-repeat="item in lane.worklist.items"
|
||||
ng-switch="item.item_type">
|
||||
ng-switch="item.item_type"
|
||||
ng-click="showCardDetail(item)">
|
||||
<div ng-switch-when="story">
|
||||
<div class="row">
|
||||
<div class="col-xs-1">
|
||||
<i class="fa fa-sb-story text-muted"></i>
|
||||
</div>
|
||||
<div class="col-xs-10">
|
||||
<a href="#!/story/{{item.story.id}}">
|
||||
<a>
|
||||
{{item.story.title}}
|
||||
</a>
|
||||
</div>
|
||||
@ -49,7 +50,7 @@
|
||||
<i class="fa fa-tasks text-muted"></i>
|
||||
</div>
|
||||
<div class="col-xs-10">
|
||||
<a href="#!/story/{{item.task.story_id}}">
|
||||
<a>
|
||||
{{item.task.title}}
|
||||
</a>
|
||||
</div>
|
||||
|
337
src/app/boards/template/card_details.html
Normal file
337
src/app/boards/template/card_details.html
Normal file
@ -0,0 +1,337 @@
|
||||
<!--
|
||||
~ Copyright (c) 2016 Codethink Limited
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<div class="panel panel-default card-modal">
|
||||
<div class="panel-heading clearfix">
|
||||
<button type="button" class="close" aria-hidden="true"
|
||||
ng-click="close()">×</button>
|
||||
<h3 class="panel-title pull-left">
|
||||
Card #{{card.id}} -
|
||||
<span ng-if="card.item_type === 'task'">
|
||||
{{card.task.title}}
|
||||
</span>
|
||||
<span ng-if="card.item_type === 'story'">
|
||||
{{card.story.title}}
|
||||
</span>
|
||||
</h3>
|
||||
</div>
|
||||
<div ng-if="card.item_type == 'task'"
|
||||
ng-include src="'/inline/task_body.html'">
|
||||
</div>
|
||||
<div ng-if="card.item_type == 'story'"
|
||||
ng-include src="'/inline/story_body.html'">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/ng-template" id="/inline/task_body.html">
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 card-heading">
|
||||
<h2>
|
||||
<span ng-show="!editingTitle">
|
||||
<i class="fa fa-tasks"></i>
|
||||
{{card.task.title}}
|
||||
<small ng-show="permissions.moveCards || permissions.editBoard">
|
||||
<a href ng-click="toggleEditTitle()">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
</small>
|
||||
</span>
|
||||
<div class="input-group" ng-show="editingTitle">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
placeholder="Task title"
|
||||
ng-model="modifications.title" />
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default"
|
||||
type="button"
|
||||
ng-click="editTitle()"
|
||||
ng-disabled="newTitle.length < 3">
|
||||
<i class="fa fa-check"></i>
|
||||
<span class="hidden-xs">Save</span>
|
||||
</button>
|
||||
<button class="btn btn-danger"
|
||||
type="button"
|
||||
ng-click="toggleEditTitle()">
|
||||
<i class="fa fa-times"></i>
|
||||
<span class="hidden-xs">Cancel</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</h2>
|
||||
<div class="text-muted">
|
||||
Task in the story
|
||||
<a href="#!/story/{{story.id}}">"{{story.title}}"</a>.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 item-heading">
|
||||
<label>
|
||||
Story description
|
||||
(<a href
|
||||
ng-click="showDescription = !showDescription"
|
||||
>{{showDescription ? 'hide' : 'show'}}</a>)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 card-detail-item" ng-show="showDescription"
|
||||
ng-click="toggleEditDescription()"
|
||||
ng-class="{'editing': editingDescription}">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<insert-markdown content="story.description"
|
||||
ng-show="!editingDescription || previewDescription">
|
||||
</insert-markdown>
|
||||
<insert-markdown content="modifications.description"
|
||||
ng-show="editingDescription && previewDescription">
|
||||
</insert-markdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" ng-show="editingDescription">
|
||||
<div class="col-xs-12">
|
||||
<textarea placeholder="Enter a story description here"
|
||||
class="form-control context-edit"
|
||||
msd-elastic
|
||||
rows="3"
|
||||
required
|
||||
focus-on-show
|
||||
ng-disabled="isUpdating"
|
||||
ng-model="modifications.description"
|
||||
ng-show="editingDescription"
|
||||
ng-click="$event.stopPropagation()">
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" ng-show="editingDescription"
|
||||
ng-click="$event.stopPropagation()">
|
||||
<div class="col-xs-6">
|
||||
<button class="btn btn-primary" type="button"
|
||||
ng-click="previewDescription = !previewDescription">
|
||||
Preview
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<button class="btn btn-primary" type="button"
|
||||
ng-click="editStoryDescription()">
|
||||
Save
|
||||
</button>
|
||||
<button class="btn btn-default" type="button"
|
||||
ng-click="toggleEditDescription()">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 item-heading">
|
||||
<label>Due date</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 card-detail-item"
|
||||
ng-class="{'editing': editingDueDate}"
|
||||
ng-click="toggleEditDueDate(); toggleDueDateDropdown()">
|
||||
<div class="row">
|
||||
<div class="col-xs-1">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</div>
|
||||
<div class="col-xs-11" ng-show="!editingDueDate">
|
||||
<span ng-show="validDueDate(card.resolved_due_date)">
|
||||
<span time-moment
|
||||
eventdate="card.resolved_due_date.date"
|
||||
format-string="'MMM Do, YYYY [at] H:mm'">
|
||||
</span>
|
||||
-
|
||||
<span class="text-muted">
|
||||
{{card.resolved_due_date.name}}
|
||||
</span>
|
||||
</span>
|
||||
<span ng-show="!validDueDate(card.resolved_due_date)">
|
||||
No due date
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-xs-11"
|
||||
ng-show="editingDueDate"
|
||||
ng-include src="'app/boards/template/card_details/edit_due_date.html'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 item-heading">
|
||||
<label>Assignee</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 card-detail-item"
|
||||
ng-class="{'editing': editingAssignee}"
|
||||
ng-click="toggleAssigneeTypeahead()">
|
||||
<user-typeahead ng-model="card.task.assignee_id"
|
||||
enabled="isLoggedIn"
|
||||
on-change="updateTask(card.task)"
|
||||
empty-prompt="Click to assign someone to this task."
|
||||
empty-disabled-prompt="Task is unassigned."
|
||||
as-inline="true"
|
||||
id="assignee"
|
||||
on-blur="toggleEditAssignee()"
|
||||
on-focus="toggleEditAssignee()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/ng-template" id="/inline/story_body.html">
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 card-heading">
|
||||
<h2>
|
||||
<span ng-show="!editingTitle">
|
||||
<i class="fa fa-sb-story"></i>
|
||||
{{card.story.title}}
|
||||
<small>
|
||||
<a href ng-click="toggleEditTitle()">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
</small>
|
||||
</span>
|
||||
<div class="input-group" ng-show="editingTitle">
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
placeholder="Story title"
|
||||
ng-model="modifications.title" />
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default"
|
||||
type="button"
|
||||
ng-click="editTitle()"
|
||||
ng-disabled="newTitle.length < 3">
|
||||
<i class="fa fa-check"></i>
|
||||
<span class="hidden-xs">Save</span>
|
||||
</button>
|
||||
<button class="btn btn-danger"
|
||||
type="button"
|
||||
ng-click="toggleEditTitle()">
|
||||
<i class="fa fa-times"></i>
|
||||
<span class="hidden-xs">Cancel</span>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 item-heading">
|
||||
<label>
|
||||
Story description
|
||||
(<a href
|
||||
ng-click="showDescription = !showDescription"
|
||||
>{{showDescription ? 'hide' : 'show'}}</a>)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 card-detail-item" ng-show="showDescription"
|
||||
ng-click="toggleEditDescription()"
|
||||
ng-class="{'editing': editingDescription}">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<insert-markdown content="story.description"
|
||||
ng-show="!editingDescription">
|
||||
</insert-markdown>
|
||||
<insert-markdown content="modifications.description"
|
||||
ng-show="editingDescription && previewDescription">
|
||||
</insert-markdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" ng-show="editingDescription">
|
||||
<div class="col-xs-12">
|
||||
<textarea placeholder="Enter a story description here"
|
||||
class="form-control context-edit"
|
||||
msd-elastic
|
||||
rows="3"
|
||||
required
|
||||
focus-on-show
|
||||
ng-disabled="isUpdating"
|
||||
ng-model="modifications.description"
|
||||
ng-show="editingDescription"
|
||||
ng-click="$event.stopPropagation()">
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" ng-show="editingDescription"
|
||||
ng-click="$event.stopPropagation()">
|
||||
<div class="col-xs-6">
|
||||
<button class="btn btn-primary" type="button"
|
||||
ng-click="previewDescription = !previewDescription">
|
||||
Preview
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<button class="btn btn-primary" type="button"
|
||||
ng-click="editStoryDescription()">
|
||||
Save
|
||||
</button>
|
||||
<button class="btn btn-default" type="button"
|
||||
ng-click="toggleEditDescription()">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 item-heading">
|
||||
<label>Due date</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-detail">
|
||||
<div class="col-xs-12 card-detail-item"
|
||||
ng-class="{'editing': editingDueDate}"
|
||||
ng-click="toggleEditDueDate(); toggleDueDateDropdown()">
|
||||
<div class="row">
|
||||
<div class="col-xs-1">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</div>
|
||||
<div class="col-xs-11" ng-show="!editingDueDate">
|
||||
<span ng-show="validDueDate(card.resolved_due_date)">
|
||||
<span time-moment
|
||||
eventdate="card.resolved_due_date.date"
|
||||
format-string="'MMM Do, YYYY [at] H:mm'">
|
||||
</span>
|
||||
-
|
||||
<span class="text-muted">
|
||||
{{card.resolved_due_date.name}}
|
||||
</span>
|
||||
</span>
|
||||
<span ng-show="!validDueDate(card.resolved_due_date)">
|
||||
No due date
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-xs-11"
|
||||
ng-show="editingDueDate"
|
||||
ng-include src="'app/boards/template/card_details/edit_due_date.html'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
78
src/app/boards/template/card_details/edit_due_date.html
Normal file
78
src/app/boards/template/card_details/edit_due_date.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!--
|
||||
~ Copyright (c) 2016 Codethink Limited
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<label>Displayed date:</label>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<span class="text-muted"
|
||||
ng-show="!relevantDates.length">
|
||||
No visible due dates.
|
||||
</span>
|
||||
|
||||
<span id="due-dates-dropdown" class="dropdown" dropdown
|
||||
ng-show="relevantDates.length"
|
||||
ng-click="$event.stopPropagation();">
|
||||
<button class="btn btn-sm btn-default dropdown-toggle"
|
||||
dropdown-toggle>
|
||||
<span ng-show="validDueDate(card.resolved_due_date)">
|
||||
<span time-moment
|
||||
eventdate="card.resolved_due_date.date"
|
||||
format-string="'MMM Do, YYYY [at] H:mm'">
|
||||
</span>
|
||||
<br/>
|
||||
<span class="text-muted">
|
||||
{{card.resolved_due_date.name}}
|
||||
</span>
|
||||
</span>
|
||||
<span ng-show="!validDueDate(card.resolved_due_date)">
|
||||
No due date
|
||||
</span>
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-click="setDisplayDate(noDate)"
|
||||
dropdown-toggle>
|
||||
<a>
|
||||
No due date
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider" role="separator"></li>
|
||||
<li ng-repeat="date in relevantDates"
|
||||
ng-click="setDisplayDate(date)"
|
||||
dropdown-toggle>
|
||||
<a>
|
||||
<span time-moment
|
||||
eventdate="date.date"
|
||||
format-string="'MMM Do, YYYY [at] H:mm'">
|
||||
</span>
|
||||
<br/>
|
||||
<span class="text-muted">
|
||||
{{date.name}}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider" role="separator"></li>
|
||||
<li ng-click="newDueDate()">
|
||||
<a>
|
||||
<i class="fa fa-plus-circle"></i>
|
||||
New due date
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
@ -193,6 +193,69 @@
|
||||
background-color: #999;
|
||||
}
|
||||
|
||||
/* Card modal style */
|
||||
|
||||
.card-modal h2 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.card-heading {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.card-detail {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
|
||||
& div.item-heading > label {
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
& label {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
};
|
||||
|
||||
/* TODO: declare this somewhere it can be overridden */
|
||||
@card-detail-item-hover: #f6f6f6;
|
||||
|
||||
.card-detail-item {
|
||||
border-radius: @border-radius-base;
|
||||
padding: 10px 15px;
|
||||
&:hover {
|
||||
background-color: @card-detail-item-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& p:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
& user-typeahead .form-group {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
& .form-control-static {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
&.editing {
|
||||
background-color: @card-detail-item-hover;
|
||||
}
|
||||
|
||||
& .dropdown-menu {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
& .row {
|
||||
margin-bottom: 5px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.due-date-modal {
|
||||
& .nav-tabs {
|
||||
margin-bottom: 10px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user