Skip to content

Commit 5563556

Browse files
committed
added goals feature. fix #15
1 parent 166f703 commit 5563556

File tree

11 files changed

+522
-3
lines changed

11 files changed

+522
-3
lines changed

appinfo/database.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,4 +521,50 @@
521521
</table>
522522

523523

524+
<table>
525+
<name>*dbprefix*timetracker_goal</name>
526+
527+
<declaration>
528+
<field>
529+
<name>id</name>
530+
<type>integer</type>
531+
<default>0</default>
532+
<notnull>true</notnull>
533+
<autoincrement>1</autoincrement>
534+
<length>4</length>
535+
</field>
536+
<field>
537+
<name>user_uid</name>
538+
<type>text</type>
539+
<notnull>true</notnull>
540+
<length>128</length>
541+
</field>
542+
<field>
543+
<name>project_id</name>
544+
<type>integer</type>
545+
<notnull>true</notnull>
546+
<length>4</length>
547+
</field>
548+
<field>
549+
<name>hours</name>
550+
<type>integer</type>
551+
<notnull>true</notnull>
552+
<length>4</length>
553+
</field>
554+
<field>
555+
<name>interval</name>
556+
<type>text</type>
557+
<notnull>true</notnull>
558+
<length>12</length>
559+
</field>
560+
<field>
561+
<name>created_at</name>
562+
<type>integer</type>
563+
<notnull>true</notnull>
564+
<length>4</length>
565+
</field>
566+
</declaration>
567+
</table>
568+
569+
524570
</database>

appinfo/routes.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
['name' => 'timelinesAdmin#index', 'url' => '/timelines-admin', 'verb' => 'GET'],
2323

2424
['name' => 'tags#index', 'url' => '/tags', 'verb' => 'GET'],
25+
['name' => 'goals#index', 'url' => '/goals', 'verb' => 'GET'],
2526

2627
['name' => 'ajax#start_timer', 'url' => '/ajax/start-timer/{name}', 'verb' => 'POST'],
2728
['name' => 'ajax#stop_timer', 'url' => '/ajax/stop-timer/{name}', 'verb' => 'POST'],
@@ -49,6 +50,11 @@
4950
['name' => 'ajax#edit_tag', 'url' => '/ajax/edit-tag/{id}', 'verb' => 'POST'],
5051
['name' => 'ajax#delete_tag', 'url' => '/ajax/delete-tag/{id}', 'verb' => 'POST'],
5152

53+
['name' => 'ajax#get_goals', 'url' => '/ajax/goals', 'verb' => 'GET'],
54+
['name' => 'ajax#add_goal', 'url' => '/ajax/add-goal', 'verb' => 'POST'],
55+
['name' => 'ajax#delete_goal', 'url' => '/ajax/delete-goal/{id}', 'verb' => 'POST'],
56+
57+
5258
['name' => 'ajax#get_report', 'url' => '/ajax/report', 'verb' => 'GET'],
5359
['name' => 'ajax#post_timeline', 'url' => '/ajax/timeline', 'verb' => 'POST'],
5460
['name' => 'ajax#get_timelines', 'url' => '/ajax/timelines', 'verb' => 'GET'],

css/style.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ td.ε_row {
273273
margin: 40px;
274274
flex-wrap: wrap;
275275
}
276+
#timetracker-goals {
277+
width: 100%;
278+
/* display: block; */
279+
/*background-color: rgb(250, 251, 252);*/
280+
display: inline-block;
281+
margin: 40px;
282+
padding: 20px;
283+
}
276284
.set-project{
277285
line-height: 32px;
278286
min-width: 200px;
@@ -346,6 +354,10 @@ td.ε_row {
346354

347355
background-image: var(--icon-folder-000);
348356
}
357+
.nav-icon-timer {
358+
359+
background-image: var(--icon-play-000);
360+
}
349361
.nav-icon-clients {
350362
background-image: var(--icon-contacts-000);
351363
}
@@ -358,6 +370,9 @@ td.ε_row {
358370
.nav-icon-dashboard {
359371
background-image: var(--icon-desktop-000);
360372
}
373+
.nav-icon-goals {
374+
background-image: var(--icon-monitoring-000);
375+
}
361376
/* .ui-button.primary {
362377
background-color: red;
363378
}

js/src/goals.js

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
var $ = require("jquery");
2+
require("jquery-migrate");
3+
// var moment = require("moment");
4+
require("jqueryui");
5+
//require("jqueryui/jquery-ui.css");
6+
import Tabulator from 'tabulator-tables';
7+
require('tabulator-tables/dist/css/tabulator.css');
8+
9+
import 'select2/dist/js/select2.full.js'
10+
require('select2/dist/css/select2.css');
11+
12+
require('../../css/style.css');
13+
(function() {
14+
$.ajaxSetup({
15+
headers: { 'RequestToken': OC.requestToken }
16+
});
17+
18+
$( function() {
19+
var newGoalProjectId;
20+
$(document).ready(function() {
21+
$("#dialog-confirm").dialog({
22+
autoOpen: false,
23+
modal: true
24+
});
25+
});
26+
27+
28+
$("#project-select").select2({
29+
width: '200px',
30+
escapeMarkup : function(markup) { return markup; },
31+
placeholder: "Select project",
32+
allowClear: true,
33+
templateResult: function formatState (project) {
34+
var color = '#ffffff';
35+
if (project.color) {
36+
color = project.color;
37+
}
38+
var $state = $(
39+
'<span class="select-project"><span class="select-project-color" style="background-color:'+color+';" ></span>' + project.text + '</span>'
40+
);
41+
return $state;
42+
},
43+
ajax: {
44+
tags: true,
45+
url: OC.generateUrl('/apps/timetracker/ajax/projects'),
46+
47+
dataType: 'json',
48+
delay: 250,
49+
50+
processResults: function (data, page) { //json parse
51+
return {
52+
results: $.map(data.Projects,function(val, i){
53+
return { id: val.id, text:val.name, color: val.color};
54+
}),
55+
pagination: {
56+
more: false,
57+
}
58+
};
59+
},
60+
cache: false,
61+
62+
},
63+
});
64+
$('#project-select').on("select2:select select2:unselect", function(e) {
65+
newGoalProjectId = ($(e.target).val() != null)? $(e.target).val() : "";
66+
});
67+
68+
69+
$("#new-goal-submit").click(function () {
70+
if ($("#new-goal-hours").val().trim() == '')
71+
return false;
72+
var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-goal');
73+
var jqxhr = $.post( baseUrl, {
74+
projectId : newGoalProjectId,
75+
hours: $("#new-goal-hours").val(),
76+
interval: $("#new-goal-interval").val(),
77+
}, function() {
78+
79+
getGoals();
80+
})
81+
.done(function(data, status, jqXHR) {
82+
var response = data;
83+
if ('Error' in response){
84+
alert(response.Error);
85+
}
86+
})
87+
.fail(function() {
88+
alert( "error" );
89+
})
90+
return false;
91+
});
92+
93+
getGoals();
94+
function getGoals(){
95+
var baseUrl = OC.generateUrl('/apps/timetracker/ajax/goals');
96+
97+
var editIcon = function(cell, formatterParams){ //plain text value
98+
return "<i class='fa fa-edit'></i>";
99+
};
100+
101+
102+
var columns = [
103+
{title:"#", field:"", formatter:"rownum", width: 40, align: "center"},
104+
{title:"Project", field:"projectName", widthGrow:1}, //column will be allocated 1/5 of the remaining space
105+
{title:"Target Hours", field:"hours", widthGrow:1}, //column will be allocated 1/5 of the remaining space
106+
{title:"Interval", field:"interval", widthGrow:1}, //column will be allocated 1/5 of the remaining space
107+
{title:"Started At", field:"createdAt", widthGrow:1, mutator: function(value, data, type, params, component){
108+
return new Date(data.createdAt*1000).toDateString();}
109+
}, //column will be allocated 1/5 of the remaining space
110+
{title:"Hours spent current interval", field:"workedHoursCurrentPeriod", widthGrow:1}, //column will be allocated 1/5 of the remaining space
111+
{title:"Past Debt in Hours", field:"debtHours", widthGrow:1}, //column will be allocated 1/5 of the remaining space
112+
{title:"Remaining Hours", field:"remainingHours", widthGrow:1}, //column will be allocated 1/5 of the remaining space
113+
{title:"Total Remaining Hours", field:"totalRemainingHours", widthGrow:1}, //column will be allocated 1/5 of the remaining space
114+
{formatter:"buttonCross", width:40, align:"center", cellClick:function(e, cell) {
115+
$("#dialog-confirm").dialog({
116+
buttons : {
117+
"Confirm" : {click: function() {
118+
var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-goal/'+cell.getRow().getData().id);
119+
var jqxhr = $.post( baseUrl, function() {
120+
getGoals();
121+
$("#dialog-confirm").dialog("close");
122+
})
123+
.done(function(data, status, jqXHR) {
124+
var response = data;
125+
if ('Error' in response){
126+
alert(response.Error);
127+
}
128+
})
129+
.fail(function() {
130+
alert( "error" );
131+
})
132+
return false;
133+
},
134+
text: 'Confirm',
135+
class:'primary'
136+
},
137+
"Cancel" : function() {
138+
$(this).dialog("close");
139+
}
140+
}
141+
});
142+
$("#dialog-confirm").dialog('open');
143+
144+
//cell.getRow().delete();
145+
}},
146+
147+
];
148+
149+
var table = new Tabulator("#goals", {
150+
ajaxURL:baseUrl,
151+
layout:"fitColumns",
152+
columns:columns,
153+
rowClick:function(e, row){
154+
return false;
155+
},
156+
ajaxResponse:function(url, params, response){
157+
158+
return response.Goals; //return the tableData property of a response json object
159+
},
160+
});
161+
}
162+
} );
163+
}());

js/webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
projects: './src/projects.js',
99
reports: './src/reports.js',
1010
tags: './src/tags.js',
11+
goals: './src/goals.js',
1112
timelines: './src/timelines.js',
1213
timelinesadmin: './src/timelines-admin.js',
1314
},

0 commit comments

Comments
 (0)