Working on kanban

This commit is contained in:
Hillel Coren 2017-12-20 10:10:25 +02:00
parent 8fd52e7bed
commit 13cf166eeb
2 changed files with 43 additions and 10 deletions

View File

@ -27,7 +27,7 @@ class TaskKanbanController extends BaseController
->get(); ->get();
$projects = Project::scope()->get(); $projects = Project::scope()->get();
$clients = Client::scope()->get(); $clients = Client::scope()->with(['contacts'])->get();
// check initial statuses exist // check initial statuses exist
if (! $statuses->count()) { if (! $statuses->count()) {
@ -61,7 +61,7 @@ class TaskKanbanController extends BaseController
$adjustment = 0; $adjustment = 0;
$counts = []; $counts = [];
foreach ($tasks as $task) { foreach ($tasks as $task) {
if (! $task->task_status_id) { if (! $task->task_status || $task->task_status->trashed()) {
$task->task_status_id = $firstStatus->id; $task->task_status_id = $firstStatus->id;
$task->setRelation('task_status', $firstStatus); $task->setRelation('task_status', $firstStatus);
} }

View File

@ -178,8 +178,10 @@
self.statuses = ko.observableArray(); self.statuses = ko.observableArray();
self.is_adding_status = ko.observable(false); self.is_adding_status = ko.observable(false);
self.new_status = ko.observable(''); self.new_status = ko.observable();
self.filter = ko.observable(''); self.filter = ko.observable();
self.filter_client_id = ko.observable();
self.filter_project_id = ko.observable();
self.is_sending_request = ko.observable(false); self.is_sending_request = ko.observable(false);
for (var i=0; i<statuses.length; i++) { for (var i=0; i<statuses.length; i++) {
@ -193,17 +195,27 @@
var project = projects[i]; var project = projects[i];
projectMap[project.public_id] = new ProjectModel(project); projectMap[project.public_id] = new ProjectModel(project);
projectList.push({ projectList.push({
type: 'project',
value: project.name, value: project.name,
tokens: project.name, tokens: project.name,
id: project.public_id,
}) })
} }
for (var i=0; i<clients.length; i++) { for (var i=0; i<clients.length; i++) {
var client = clients[i]; var client = clients[i];
clientMap[client.public_id] = new ClientModel(client); clientMap[client.public_id] = new ClientModel(client);
var tokens = [client.name];
if (client.contacts.length) {
$.each(client.contacts, function(i, contact) {
tokens.push(contact.first_name, contact.last_name, contact.email);
});
}
clientList.push({ clientList.push({
value: client.name, type: 'client',
tokens: client.name, value: getClientDisplayName(client),
tokens: tokens,
id: client.public_id,
}) })
} }
@ -423,7 +435,7 @@
'&task_status_sort_order=' + self.task_status_sort_order(); '&task_status_sort_order=' + self.task_status_sort_order();
} }
self.matchesFilter = function(filter) { self.matchesFilter = function(filter, clientId, projectId) {
if (filter) { if (filter) {
filter = filter.toLowerCase(); filter = filter.toLowerCase();
var parts = filter.split(' '); var parts = filter.split(' ');
@ -453,6 +465,18 @@
} }
} }
if (clientId) {
if (! self.client() || self.client().public_id() != clientId) {
return false;
}
}
if (projectId) {
if (! self.project() || self.project().public_id() != projectId) {
return false;
}
}
return true; return true;
} }
@ -554,11 +578,20 @@
header: '&nbsp;<span style="font-weight:600;font-size:15px">{{ trans('texts.projects') }}</span>' header: '&nbsp;<span style="font-weight:600;font-size:15px">{{ trans('texts.projects') }}</span>'
} }
}).on('typeahead:selected', function(element, datum, name) { }).on('typeahead:selected', function(element, datum, name) {
model.filter(datum.value); model.filter(false);
if (datum.type == 'client') {
model.filter_client_id(datum.id);
model.filter_project_id(false);
} else {
model.filter_project_id(datum.id);
model.filter_client_id(false);
}
}); });
$('#filter').on('keyup', function() { $('#filter').on('input', function() {
model.filter($('#filter').val()); model.filter($('#filter').val());
model.filter_client_id(false);
model.filter_project_id(false);
}); });
window.model = new ViewModel(); window.model = new ViewModel();
@ -585,7 +618,7 @@
</div> </div>
<div data-bind="sortable: { data: tasks, as: 'task', afterMove: onTaskDragged, allowDrop: true, connectClass: 'connect-row' }" style="min-height:16px"> <div data-bind="sortable: { data: tasks, as: 'task', afterMove: onTaskDragged, allowDrop: true, connectClass: 'connect-row' }" style="min-height:16px">
<div class="kanban-column-row" data-bind="css: { editing: is_editing_task }, visible: task.matchesFilter($root.filter())"> <div class="kanban-column-row" data-bind="css: { editing: is_editing_task }, visible: task.matchesFilter($root.filter(), $root.filter_client_id(), $root.filter_project_id())">
<div data-bind="event: { click: startEditTask }"> <div data-bind="event: { click: startEditTask }">
<div class="view panel" data-bind="css: { running: is_running }"> <div class="view panel" data-bind="css: { running: is_running }">
<i class="fa fa-circle" data-bind="visible: project, css: projectColor"></i> <i class="fa fa-circle" data-bind="visible: project, css: projectColor"></i>