mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on time tracker
This commit is contained in:
parent
c1ff189e35
commit
068c8c8a13
@ -3,9 +3,10 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
use App\Http\Requests;
|
use App\Http\Requests;
|
||||||
use App\Models\Task;
|
use App\Models\Task;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Models\Project;
|
||||||
|
|
||||||
class TimeTrackerController extends Controller
|
class TimeTrackerController extends Controller
|
||||||
{
|
{
|
||||||
@ -17,6 +18,8 @@ class TimeTrackerController extends Controller
|
|||||||
$data = [
|
$data = [
|
||||||
'title' => trans('texts.time_tracker'),
|
'title' => trans('texts.time_tracker'),
|
||||||
'tasks' => Task::scope()->with('project', 'client.contacts')->get(),
|
'tasks' => Task::scope()->with('project', 'client.contacts')->get(),
|
||||||
|
'clients' => Client::scope()->with('contacts')->orderBy('name')->get(),
|
||||||
|
'projects' => Project::scope()->with('client.contacts')->orderBy('name')->get(),
|
||||||
'account' => $account,
|
'account' => $account,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
||||||
.form-control {
|
.panel-body .form-control {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:focus {
|
a:focus {
|
||||||
@ -85,6 +85,13 @@
|
|||||||
|
|
||||||
<div style="height:74px"></div>
|
<div style="height:74px"></div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div data-bind="text: ko.toJSON(model.selectedTask().client_id)"></div>
|
||||||
|
<div data-bind="text: ko.toJSON(model.selectedTask().client)"></div>
|
||||||
|
<div data-bind="text: ko.toJSON(model.selectedTask().project_id)"></div>
|
||||||
|
<div data-bind="text: ko.toJSON(model.selectedTask().project)"></div>
|
||||||
|
-->
|
||||||
|
|
||||||
<div class="container" style="margin: 0 auto;width: 100%;">
|
<div class="container" style="margin: 0 auto;width: 100%;">
|
||||||
<div class="row no-gutter">
|
<div class="row no-gutter">
|
||||||
|
|
||||||
@ -93,10 +100,15 @@
|
|||||||
<div class="well" data-bind="visible: selectedTask" style="padding-bottom:0px; margin-bottom:0px; display:none;">
|
<div class="well" data-bind="visible: selectedTask" style="padding-bottom:0px; margin-bottom:0px; display:none;">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{!! Former::select('client')->addOption('', '')->addGroupClass('client-select') !!}
|
{!! Former::select('client_id')
|
||||||
|
->addOption('', '')
|
||||||
|
->label('client')
|
||||||
|
->data_bind("dropdown: selectedTask().client_id")
|
||||||
|
->addGroupClass('client-select') !!}
|
||||||
{!! Former::select('project_id')
|
{!! Former::select('project_id')
|
||||||
->addOption('', '')
|
->addOption('', '')
|
||||||
->addGroupClass('project-select')
|
->addGroupClass('project-select')
|
||||||
|
->data_bind("dropdown: selectedTask().project_id")
|
||||||
->label(trans('texts.project')) !!}
|
->label(trans('texts.project')) !!}
|
||||||
{!! Former::textarea('description')
|
{!! Former::textarea('description')
|
||||||
->data_bind("value: selectedTask().description, valueUpdate: 'afterkeydown'")
|
->data_bind("value: selectedTask().description, valueUpdate: 'afterkeydown'")
|
||||||
@ -126,9 +138,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<h4 class="list-group-item-heading" data-bind="text: description"></h4>
|
<h4 class="list-group-item-heading" data-bind="text: description"></h4>
|
||||||
<p class="list-group-item-text">
|
<p class="list-group-item-text">
|
||||||
<span class="link" data-bind="text: client.displayName, click: $parent.viewClient, clickBubble: false"></span>
|
<span class="link" data-bind="text: clientName, click: $parent.viewClient, clickBubble: false"></span>
|
||||||
<span data-bind="visible: client.displayName && project && project.name"> | </span>
|
<span data-bind="visible: clientName && projectName && project.name"> | </span>
|
||||||
<span class="link" data-bind="text: project ? project.name : ' ', click: $parent.viewProject, clickBubble: false"></span>
|
<span class="link" data-bind="text: projectName, click: $parent.viewProject, clickBubble: false"></span>
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -139,6 +151,8 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
var tasks = {!! $tasks !!};
|
var tasks = {!! $tasks !!};
|
||||||
|
var clients = {!! $clients !!};
|
||||||
|
var projects = {!! $projects !!};
|
||||||
var dateTimeFormat = '{{ $account->getMomentDateTimeFormat() }}';
|
var dateTimeFormat = '{{ $account->getMomentDateTimeFormat() }}';
|
||||||
var timezone = '{{ $account->getTimezone() }}';
|
var timezone = '{{ $account->getTimezone() }}';
|
||||||
|
|
||||||
@ -190,7 +204,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.tock = function(startTime) {
|
self.tock = function(startTime) {
|
||||||
console.log('tock..');
|
|
||||||
self.clock(self.clock() + 1);
|
self.clock(self.clock() + 1);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
model.tock();
|
model.tock();
|
||||||
@ -249,7 +262,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.selectTask = function(task) {
|
self.selectTask = function(task) {
|
||||||
self.filter('');
|
//self.filter('');
|
||||||
self.selectedTask(task);
|
self.selectedTask(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -258,6 +271,8 @@
|
|||||||
var self = this;
|
var self = this;
|
||||||
self.description = ko.observable('test');
|
self.description = ko.observable('test');
|
||||||
self.time_log = ko.observableArray();
|
self.time_log = ko.observableArray();
|
||||||
|
self.client_id = ko.observable();
|
||||||
|
self.project_id = ko.observable();
|
||||||
self.client = false;
|
self.client = false;
|
||||||
self.project = false;
|
self.project = false;
|
||||||
self.actionButtonVisible = ko.observable(false);
|
self.actionButtonVisible = ko.observable(false);
|
||||||
@ -265,11 +280,13 @@
|
|||||||
self.mapping = {
|
self.mapping = {
|
||||||
'client': {
|
'client': {
|
||||||
create: function(data) {
|
create: function(data) {
|
||||||
|
self.client_id(data.data.public_id);
|
||||||
return new ClientModel(data.data);
|
return new ClientModel(data.data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'project': {
|
'project': {
|
||||||
create: function(data) {
|
create: function(data) {
|
||||||
|
self.project_id(data.data.public_id);
|
||||||
return data.data ? new ProjectModel(data.data) : null;
|
return data.data ? new ProjectModel(data.data) : null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -348,6 +365,14 @@
|
|||||||
return time.isRunning();
|
return time.isRunning();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.clientName = ko.computed(function() {
|
||||||
|
return self.client_id() && self.client ? self.client.displayName() : '';
|
||||||
|
});
|
||||||
|
|
||||||
|
self.projectName = ko.computed(function() {
|
||||||
|
return self.project_id() && self.project ? self.project.name() : '';
|
||||||
|
});
|
||||||
|
|
||||||
self.startClass = ko.computed(function() {
|
self.startClass = ko.computed(function() {
|
||||||
return self.isRunning() ? 'btn-danger' : 'btn-success';
|
return self.isRunning() ? 'btn-danger' : 'btn-success';
|
||||||
});
|
});
|
||||||
@ -425,8 +450,6 @@
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ko.mapping.fromJS(data, self.mapping, this);
|
ko.mapping.fromJS(data, self.mapping, this);
|
||||||
} else {
|
|
||||||
self.addContact();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,7 +497,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
self.age = ko.computed(function() {
|
self.age = ko.computed(function() {
|
||||||
console.log(moment.unix(self.startTime()).toString());
|
|
||||||
return moment.unix(self.startTime()).fromNow();
|
return moment.unix(self.startTime()).fromNow();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -528,6 +550,102 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
|
// setup clients and project comboboxes
|
||||||
|
var clientMap = {};
|
||||||
|
var projectMap = {};
|
||||||
|
var projectsForClientMap = {};
|
||||||
|
var projectsForAllClients = [];
|
||||||
|
var $clientSelect = $('select#client_id');
|
||||||
|
|
||||||
|
for (var i=0; i<projects.length; i++) {
|
||||||
|
var project = projects[i];
|
||||||
|
projectMap[project.public_id] = project;
|
||||||
|
|
||||||
|
var client = project.client;
|
||||||
|
if (!client) {
|
||||||
|
projectsForAllClients.push(project);
|
||||||
|
} else {
|
||||||
|
if (!projectsForClientMap.hasOwnProperty(client.public_id)) {
|
||||||
|
projectsForClientMap[client.public_id] = [];
|
||||||
|
}
|
||||||
|
projectsForClientMap[client.public_id].push(project);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<clients.length; i++) {
|
||||||
|
var client = clients[i];
|
||||||
|
clientMap[client.public_id] = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clientSelect.append(new Option('', ''));
|
||||||
|
for (var i=0; i<clients.length; i++) {
|
||||||
|
var client = clients[i];
|
||||||
|
var clientName = getClientDisplayName(client);
|
||||||
|
if (!clientName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$clientSelect.append(new Option(clientName, client.public_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
$clientSelect.combobox();
|
||||||
|
$clientSelect.on('change', function(e) {
|
||||||
|
var clientId = $('input[name=client_id]').val();
|
||||||
|
var projectId = $('input[name=project_id]').val();
|
||||||
|
var client = clientMap[clientId];
|
||||||
|
var project = projectMap[projectId];
|
||||||
|
if (project && ((project.client && project.client.public_id == clientId) || !project.client)) {
|
||||||
|
e.preventDefault();return;
|
||||||
|
}
|
||||||
|
if (window.model && model.selectedTask()) {
|
||||||
|
model.selectedTask().client = new ClientModel(client);
|
||||||
|
model.selectedTask().client_id(clientId);
|
||||||
|
model.selectedTask().project = false;
|
||||||
|
model.selectedTask().project_id(0);
|
||||||
|
}
|
||||||
|
$projectCombobox = $('select#project_id');
|
||||||
|
$projectCombobox.find('option').remove().end().combobox('refresh');
|
||||||
|
$projectCombobox.append(new Option('', ''));
|
||||||
|
@if (Auth::user()->can('create', ENTITY_PROJECT))
|
||||||
|
if (clientId) {
|
||||||
|
$projectCombobox.append(new Option("{{ trans('texts.create_project')}}: $name", '-1'));
|
||||||
|
}
|
||||||
|
@endif
|
||||||
|
var list = clientId ? (projectsForClientMap.hasOwnProperty(clientId) ? projectsForClientMap[clientId] : []).concat(projectsForAllClients) : projects;
|
||||||
|
for (var i=0; i<list.length; i++) {
|
||||||
|
var project = list[i];
|
||||||
|
$projectCombobox.append(new Option(project.name, project.public_id));
|
||||||
|
}
|
||||||
|
$('select#project_id').combobox('refresh');
|
||||||
|
});
|
||||||
|
|
||||||
|
var $projectSelect = $('select#project_id').on('change', function(e) {
|
||||||
|
$clientCombobox = $('select#client_id');
|
||||||
|
var projectId = $('input[name=project_id]').val();
|
||||||
|
if (projectId == '-1') {
|
||||||
|
$('input[name=project_name]').val(projectName);
|
||||||
|
} else if (projectId) {
|
||||||
|
var project = projectMap[projectId];
|
||||||
|
model.selectedTask().project_id(projectId);
|
||||||
|
model.selectedTask().project = new ProjectModel(project);
|
||||||
|
// when selecting a project make sure the client is loaded
|
||||||
|
if (project && project.client) {
|
||||||
|
var client = clientMap[project.client.public_id];
|
||||||
|
if (client) {
|
||||||
|
project.client = client;
|
||||||
|
model.selectedTask().client = new ClientModel(client);
|
||||||
|
model.selectedTask().client_id(client.public_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$clientSelect.trigger('change');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
@include('partials/entity_combobox', ['entityType' => ENTITY_PROJECT])
|
||||||
|
|
||||||
|
$clientSelect.trigger('change');
|
||||||
|
|
||||||
window.model = new ViewModel();
|
window.model = new ViewModel();
|
||||||
for (var i=0; i<tasks.length; i++) {
|
for (var i=0; i<tasks.length; i++) {
|
||||||
var task = tasks[i];
|
var task = tasks[i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user