knjtasks 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +66 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/files/database_schema.rb +174 -0
- data/lib/knjtasks.rb +172 -0
- data/locales/da_DK/LC_MESSAGES/default.mo +0 -0
- data/locales/da_DK/LC_MESSAGES/default.po +1153 -0
- data/locales/da_DK/title.txt +1 -0
- data/locales/en_GB/title.txt +1 -0
- data/models/class_comment.rb +44 -0
- data/models/class_customer.rb +13 -0
- data/models/class_email_check.rb +7 -0
- data/models/class_project.rb +22 -0
- data/models/class_task.rb +163 -0
- data/models/class_task_assigned_user.rb +62 -0
- data/models/class_task_check.rb +26 -0
- data/models/class_timelog.rb +82 -0
- data/models/class_user.rb +125 -0
- data/models/class_user_project_link.rb +66 -0
- data/models/class_user_rank.rb +3 -0
- data/models/class_user_rank_link.rb +17 -0
- data/models/class_user_task_list_link.rb +17 -0
- data/pages/admin.rhtml +7 -0
- data/pages/comment_edit.rhtml +121 -0
- data/pages/comment_update_id_per_obj.rhtml +41 -0
- data/pages/customer_edit.rhtml +69 -0
- data/pages/customer_search.rhtml +80 -0
- data/pages/customer_show.rhtml +50 -0
- data/pages/frontpage.rhtml +198 -0
- data/pages/project_edit.rhtml +129 -0
- data/pages/project_search.rhtml +82 -0
- data/pages/project_show.rhtml +203 -0
- data/pages/task_check_edit.rhtml +98 -0
- data/pages/task_edit.rhtml +168 -0
- data/pages/task_search.rhtml +131 -0
- data/pages/task_show.rhtml +454 -0
- data/pages/timelog_edit.rhtml +134 -0
- data/pages/timelog_search.rhtml +318 -0
- data/pages/user_edit.rhtml +223 -0
- data/pages/user_login.rhtml +83 -0
- data/pages/user_profile.rhtml +89 -0
- data/pages/user_rank_search.rhtml +95 -0
- data/pages/user_search.rhtml +136 -0
- data/pages/user_show.rhtml +87 -0
- data/pages/workstatus.rhtml +320 -0
- data/scripts/fckeditor_validate_login.rb +23 -0
- data/spec/knjtasks_spec.rb +115 -0
- data/spec/spec_helper.rb +12 -0
- data/threads/thread_mail_task_comments.rb +114 -0
- data/www/api/task.rhtml +9 -0
- data/www/api/user.rhtml +20 -0
- data/www/clean.rhtml +14 -0
- data/www/css/default.css +186 -0
- data/www/gfx/body_bg.jpg +0 -0
- data/www/gfx/button_bg.png +0 -0
- data/www/gfx/main_box_design.png +0 -0
- data/www/gfx/main_box_left.png +0 -0
- data/www/gfx/main_box_right.png +0 -0
- data/www/gfx/main_box_top.png +0 -0
- data/www/gfx/main_box_top_left.png +0 -0
- data/www/gfx/main_box_top_right.png +0 -0
- data/www/index.rhtml +154 -0
- data/www/js/default.js +112 -0
- metadata +208 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
<%
|
2
|
+
if _get["choice"] == "dosave"
|
3
|
+
save_hash = {
|
4
|
+
:name => _post["texname"],
|
5
|
+
:descr => _post["texdescr"]
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
if _get["check_id"].to_i > 0
|
10
|
+
check = _ob.get(:Task_check, _get["check_id"])
|
11
|
+
url = "&check_id=#{check.id}"
|
12
|
+
|
13
|
+
if _get["choice"] == "dosave"
|
14
|
+
check.update(save_hash)
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
if _get["choice"] == "dodelete"
|
19
|
+
_ob.delete(check)
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
if _get["choice"] == "setcheck"
|
24
|
+
check.update(:checked => _get["checkval"].to_i)
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
else
|
28
|
+
task = _ob.get(:Task, _get["task_id"])
|
29
|
+
url = "&task_id=#{task.id}"
|
30
|
+
|
31
|
+
if _get["choice"] == "dosave"
|
32
|
+
save_hash[:task_id] = task.id
|
33
|
+
check = _ob.add(:Task_check, save_hash)
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
%>
|
38
|
+
|
39
|
+
<form id="formtaskcheck" method="get" onsubmit="return do_task_check_save();">
|
40
|
+
|
41
|
+
<%=_site.boxt(_("Enter details"), "450px")%>
|
42
|
+
<table class="form">
|
43
|
+
<%
|
44
|
+
print Knj::Web.inputs([{
|
45
|
+
:title => _("Name"),
|
46
|
+
:name => :texname,
|
47
|
+
:value => [check, :name],
|
48
|
+
:descr => _("The name of the check as it should appear for the other users.")
|
49
|
+
},{
|
50
|
+
:title => _("Description"),
|
51
|
+
:name => :texdescr,
|
52
|
+
:value => [check, :descr],
|
53
|
+
:type => :textarea,
|
54
|
+
:height => 100,
|
55
|
+
:descr => _("A description that describes what should be done before marking this check.")
|
56
|
+
}])
|
57
|
+
%>
|
58
|
+
<tr>
|
59
|
+
<td colspan="2" class="buttons">
|
60
|
+
<%if check%>
|
61
|
+
<input type="button" value="<%=_"Delete"%>" onclick="if (confirm('<%=_("Do you want to delete this check?")%>')){}" />
|
62
|
+
<%end%>
|
63
|
+
<input type="submit" value="<%=_("Save")%>" />
|
64
|
+
</td>
|
65
|
+
</tr>
|
66
|
+
</table>
|
67
|
+
<%=_site.boxb%>
|
68
|
+
|
69
|
+
</form>
|
70
|
+
|
71
|
+
<script type="text/javascript">
|
72
|
+
modal_on_opened(function(){
|
73
|
+
$("#texname").focus();
|
74
|
+
});
|
75
|
+
|
76
|
+
function do_task_check_save(){
|
77
|
+
$.ajax({
|
78
|
+
type: "POST",
|
79
|
+
url: "clean.rhtml?show=task_check_edit&choice=dosave<%=url%>",
|
80
|
+
data: forms_inputs_read($("#formtaskcheck")),
|
81
|
+
cache: false,
|
82
|
+
async: false,
|
83
|
+
complete: function(data){
|
84
|
+
if (data.responseText.length > 0){
|
85
|
+
alert(data.responseText);
|
86
|
+
}
|
87
|
+
|
88
|
+
<%if !check%>
|
89
|
+
events.call("on_task_check_added");
|
90
|
+
<%end%>
|
91
|
+
|
92
|
+
events.call("do_task_check_update");
|
93
|
+
modal_close();
|
94
|
+
}
|
95
|
+
});
|
96
|
+
return false;
|
97
|
+
}
|
98
|
+
</script>
|
@@ -0,0 +1,168 @@
|
|
1
|
+
<%
|
2
|
+
if _get["choice"] == "dosave"
|
3
|
+
save_hash = {
|
4
|
+
:name => _post["texname"],
|
5
|
+
:descr => _post["texdescr"],
|
6
|
+
:project_id => _post["selproject"],
|
7
|
+
:type => _post["seltype"],
|
8
|
+
:status => _post["selstatus"],
|
9
|
+
:priority => _post["selpriority"]
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
if _get["task_id"].to_i > 0
|
14
|
+
task = _ob.get(:Task, _get["task_id"])
|
15
|
+
title = sprintf(_("Edit task: %s."), task.name.html)
|
16
|
+
project_id = task[:project_id]
|
17
|
+
|
18
|
+
if _get["choice"] == "dosave"
|
19
|
+
task.update(save_hash)
|
20
|
+
_hb.redirect("?show=task_show&task_id=#{task.id}")
|
21
|
+
end
|
22
|
+
|
23
|
+
if _get["choice"] == "dodelete"
|
24
|
+
_ob.delete(task)
|
25
|
+
_hb.redirect("?show=task_search")
|
26
|
+
end
|
27
|
+
else
|
28
|
+
title = _("Add new task")
|
29
|
+
project_id = _get["project_id"] if _get["project_id"].to_i > 0
|
30
|
+
|
31
|
+
if _get["choice"] == "dosave"
|
32
|
+
begin
|
33
|
+
task = _ob.add(:Task, save_hash)
|
34
|
+
_hb.redirect("?show=task_show&task_id=#{task.id}")
|
35
|
+
rescue => e
|
36
|
+
_hb.alert(e.message).back
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
project_opts = _ob.list_optshash(:Project)
|
42
|
+
if project_opts.empty?
|
43
|
+
_hb.alert(_("No projects has been added to this installation yet - please do that first.")).back
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
#Generate user-projects for the select-box.
|
48
|
+
projects_opts = {"" => _("None")}
|
49
|
+
|
50
|
+
if _site.has_rank?("admin")
|
51
|
+
_ob.list(:Project) do |project|
|
52
|
+
projects_opts[project.id] = project.name
|
53
|
+
end
|
54
|
+
else
|
55
|
+
_site.user.projects.each do |link|
|
56
|
+
projects_opts[link[:project_id]] = link.project.name
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
sorted = projects_opts.sort do |a, b|
|
61
|
+
if a[0] == ""
|
62
|
+
ret = -1
|
63
|
+
elsif b[0] == ""
|
64
|
+
ret = 1
|
65
|
+
else
|
66
|
+
ret = a[1].downcase <=> b[1].downcase
|
67
|
+
end
|
68
|
+
|
69
|
+
ret
|
70
|
+
end
|
71
|
+
|
72
|
+
projects_opts = {}
|
73
|
+
sorted.each do |sort|
|
74
|
+
projects_opts[sort[0]] = sort[1]
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
#Write page title.
|
79
|
+
print _site.header(title)
|
80
|
+
%>
|
81
|
+
|
82
|
+
<form method="post" action="?show=task_edit&choice=dosave<%if task; print "&task_id=#{task.id}"; end%>">
|
83
|
+
|
84
|
+
<%=_site.boxt(_("Enter details"), 700)%>
|
85
|
+
<table class="form">
|
86
|
+
<%
|
87
|
+
priority_opts = {}
|
88
|
+
1.upto(10) do |count|
|
89
|
+
priority_opts[count] = count
|
90
|
+
end
|
91
|
+
|
92
|
+
print _hb.inputs({
|
93
|
+
:title => _("Name"),
|
94
|
+
:name => :texname,
|
95
|
+
:value => [task, :name],
|
96
|
+
:descr => _("The name of the task as it should appear in this system.")
|
97
|
+
},{
|
98
|
+
:title => _("Project"),
|
99
|
+
:name => :selproject,
|
100
|
+
:value => project_id,
|
101
|
+
:opts => projects_opts,
|
102
|
+
:descr => _("The project that this task belongs under.")
|
103
|
+
},{
|
104
|
+
:title => _("Type"),
|
105
|
+
:name => :seltype,
|
106
|
+
:value => [task, :type],
|
107
|
+
:descr => _("The type of the task."),
|
108
|
+
:opts => _ob.static(:Task, :type_opts)
|
109
|
+
},{
|
110
|
+
:title => _("Status"),
|
111
|
+
:name => :selstatus,
|
112
|
+
:value => [task, :status],
|
113
|
+
:descr => _("The status of the task."),
|
114
|
+
:opts => _ob.static(:Task, :status_opts)
|
115
|
+
},{
|
116
|
+
:title => _("Priority"),
|
117
|
+
:name => :selpriority,
|
118
|
+
:value => [task, :priority],
|
119
|
+
:opts => priority_opts,
|
120
|
+
:descr => _("10 for most important and 1 for least important.")
|
121
|
+
},{
|
122
|
+
:title => _("Description"),
|
123
|
+
:name => :texdescr,
|
124
|
+
:value => [task, :descr],
|
125
|
+
:descr => _("The description as it should appear for the users."),
|
126
|
+
:type => :fckeditor,
|
127
|
+
:height => 500
|
128
|
+
})
|
129
|
+
%>
|
130
|
+
<tr>
|
131
|
+
<td colspan="2" class="buttons">
|
132
|
+
<input type="button" value="<%=_"Insert browser and os"%>" onclick="insert_browser_and_os()" />
|
133
|
+
<%if task%>
|
134
|
+
<input type="button" value="<%=_("Show")%>" onclick="location.href='?show=task_show&task_id=<%=task.id%>';" />
|
135
|
+
<input type="button" value="<%=_("Delete")%>" onclick="if (confirm('<%=_("Do you want to delete this task?")%>')){location.href='?show=task_edit&task_id=<%=task.id%>&choice=dodelete';}" />
|
136
|
+
<%end%>
|
137
|
+
<input type="submit" value="<%=_("Save")%>" />
|
138
|
+
</td>
|
139
|
+
</tr>
|
140
|
+
</table>
|
141
|
+
<%=_site.boxb%>
|
142
|
+
|
143
|
+
</form>
|
144
|
+
|
145
|
+
<%
|
146
|
+
browser = Knj::Web.browser
|
147
|
+
%>
|
148
|
+
|
149
|
+
<script type="text/javascript">
|
150
|
+
$("#texname").focus()
|
151
|
+
|
152
|
+
var browser_and_os_inserted = false
|
153
|
+
$("#seltype").change(function(){
|
154
|
+
if (this.value == "bug" && !browser_and_os_inserted){
|
155
|
+
insert_browser_and_os()
|
156
|
+
}
|
157
|
+
})
|
158
|
+
|
159
|
+
function insert_browser_and_os(){
|
160
|
+
browser_and_os_inserted = true
|
161
|
+
|
162
|
+
fck = FCKeditorAPI.GetInstance("texdescr")
|
163
|
+
fck.InsertHtml(" ")
|
164
|
+
fck.InsertHtml("<b><%=_'Browser'%>:</b> <%=Knj::Web.html(browser['title'])%><br />")
|
165
|
+
fck.InsertHtml("<b><%=_'Version'%>:</b> " + $.browser.version + "<br />")
|
166
|
+
fck.InsertHtml("<b><%=_'Operating system'%>:</b> <%=Knj::Web.html(Php4r.ucwords(browser['os']))%> <%=Knj::Web.html(browser['os_version'])%><br />")
|
167
|
+
}
|
168
|
+
</script>
|
@@ -0,0 +1,131 @@
|
|
1
|
+
<%
|
2
|
+
print _site.header(_("Search for tasks"))
|
3
|
+
%>
|
4
|
+
|
5
|
+
<form method="get">
|
6
|
+
<%=Knj::Web.hiddens([{:name => :show, :value => :task_search}, {:name => :choice, :value => :dosearch}])%>
|
7
|
+
|
8
|
+
<%=_site.boxt(_("Enter criteria"), 350)%>
|
9
|
+
<table class="form">
|
10
|
+
<%
|
11
|
+
if _site.has_rank?(:admin)
|
12
|
+
users = _ob.list(:User)
|
13
|
+
else
|
14
|
+
users = _site.user.users_list
|
15
|
+
end
|
16
|
+
|
17
|
+
users_opts = {"" => _("All")}
|
18
|
+
users.each do |user|
|
19
|
+
users_opts[user.id] = user.name
|
20
|
+
end
|
21
|
+
|
22
|
+
users = nil
|
23
|
+
|
24
|
+
print _hb.inputs({
|
25
|
+
:title => _("Name"),
|
26
|
+
:name => :texname,
|
27
|
+
:value => _get["texname"],
|
28
|
+
:descr => _("A part of the name of the task you are looking for.")
|
29
|
+
},{
|
30
|
+
:title => _("Description"),
|
31
|
+
:name => :texdescr,
|
32
|
+
:value => _get["texdescr"],
|
33
|
+
:descr => _("A part of the description of the task you are looking for.")
|
34
|
+
},{
|
35
|
+
:title => _("Status"),
|
36
|
+
:name => :selstatus,
|
37
|
+
:opts => {"" => _("All")}.merge(_ob.static(:Task, :status_opts)),
|
38
|
+
:descr => _("If you only want to find tasks with a specific status."),
|
39
|
+
:value => _get["selstatus"]
|
40
|
+
},{
|
41
|
+
:title => _("Type"),
|
42
|
+
:name => :seltype,
|
43
|
+
:opts => {"" => _("All")}.merge(_ob.static(:Task, :type_opts)),
|
44
|
+
:descr => _("If you only want to find tasks of a specific type."),
|
45
|
+
:value => _get["seltype"]
|
46
|
+
},{
|
47
|
+
:title => _("User"),
|
48
|
+
:name => :seluser,
|
49
|
+
:opts => users_opts,
|
50
|
+
:value => _get["seluser"],
|
51
|
+
:descr => _("If you only want to see tasks from a specific user.")
|
52
|
+
})
|
53
|
+
%>
|
54
|
+
<tr>
|
55
|
+
<td colspan="2" class="buttons">
|
56
|
+
<input type="button" value="<%=_"Add new"%>" onclick="location.href='?show=task_edit';" />
|
57
|
+
<input type="submit" value="<%=_"Search"%>" />
|
58
|
+
</td>
|
59
|
+
</tr>
|
60
|
+
</table>
|
61
|
+
<%=_site.boxb%>
|
62
|
+
|
63
|
+
</form>
|
64
|
+
|
65
|
+
<script type="text/javascript">
|
66
|
+
$("#texname").focus()
|
67
|
+
</script>
|
68
|
+
|
69
|
+
<%
|
70
|
+
if _get["choice"] == "dosearch"
|
71
|
+
args = {"orderby" => "name"}
|
72
|
+
args["name_search"] = _get["texname"] if _get["texname"].to_s.length > 0
|
73
|
+
args["descr_search"] = _get["texdescr"] if _get["texdescr"].to_s.length > 0
|
74
|
+
args["status"] = _get["selstatus"] if _get["selstatus"].to_s.length > 0
|
75
|
+
args["type"] = _get["seltype"] if _get["seltype"].to_s.length > 0
|
76
|
+
args["user_id"] = _get["seluser"] if _get["seluser"].to_i > 0
|
77
|
+
|
78
|
+
%>
|
79
|
+
<br />
|
80
|
+
|
81
|
+
<%=_site.boxt(_("Results"), 900)%>
|
82
|
+
<table class="list">
|
83
|
+
<thead>
|
84
|
+
<tr>
|
85
|
+
<th><%=_"Name"%></th>
|
86
|
+
<th><%=_"Status"%></th>
|
87
|
+
<th><%=_"Project"%></th>
|
88
|
+
<th><%=_"Author"%></th>
|
89
|
+
</tr>
|
90
|
+
</thead>
|
91
|
+
<tbody>
|
92
|
+
<%
|
93
|
+
count = 0
|
94
|
+
_ob.list(:Task, args) do |task|
|
95
|
+
next if !task.has_view_access?(_site.user)
|
96
|
+
count += 1
|
97
|
+
|
98
|
+
%>
|
99
|
+
<tr>
|
100
|
+
<td>
|
101
|
+
<%=task.html%>
|
102
|
+
</td>
|
103
|
+
<td>
|
104
|
+
<%=task.status_str.html%>
|
105
|
+
</td>
|
106
|
+
<td>
|
107
|
+
<%=task.project_html%>
|
108
|
+
</td>
|
109
|
+
<td>
|
110
|
+
<%=task.user_html%>
|
111
|
+
</td>
|
112
|
+
</tr>
|
113
|
+
<%
|
114
|
+
end
|
115
|
+
|
116
|
+
if count <= 0
|
117
|
+
%>
|
118
|
+
<tr>
|
119
|
+
<td colspan="1" class="error">
|
120
|
+
<%=_("No tasks were found.")%>
|
121
|
+
</td>
|
122
|
+
</tr>
|
123
|
+
<%
|
124
|
+
end
|
125
|
+
%>
|
126
|
+
</tbody>
|
127
|
+
</table>
|
128
|
+
<%=_site.boxb%>
|
129
|
+
<%
|
130
|
+
end
|
131
|
+
%>
|
@@ -0,0 +1,454 @@
|
|
1
|
+
<%
|
2
|
+
if _get["choice"] == "removeassigned"
|
3
|
+
link = _ob.get(:Task_assigned_user, _get["link_id"])
|
4
|
+
task = link.task
|
5
|
+
_hb.alert(_("You do not have access to that task and cannot view this page.")).back if !task.has_view_access?(_site.user)
|
6
|
+
_ob.delete(link)
|
7
|
+
exit
|
8
|
+
end
|
9
|
+
|
10
|
+
task = _ob.get(:Task, _get["task_id"])
|
11
|
+
_hb.alert(_("You do not have access to that task and cannot view this page.")).back if !task.has_view_access?(_site.user)
|
12
|
+
|
13
|
+
tlogs = task.timelogs("orderby" => [["date", "desc"]])
|
14
|
+
|
15
|
+
if _get["choice"] == "getcomments"
|
16
|
+
comments = task.comments("orderby" => ["date_saved", "id"])
|
17
|
+
|
18
|
+
comments.each do |comment|
|
19
|
+
%>
|
20
|
+
<div class="comment_<%=comment.id%>" style="padding-bottom: 25px;">
|
21
|
+
<table style="width: 100%;">
|
22
|
+
<tr>
|
23
|
+
<td style="white-space: nowrap; width: 25px;">
|
24
|
+
#<%=Knj::Locales.number_out(comment[:id_per_obj], 0)%>
|
25
|
+
</td>
|
26
|
+
<td style="font-weight: bold;">
|
27
|
+
<%=comment.user_html%>
|
28
|
+
</td>
|
29
|
+
<td style="width: 260px; text-align: right; font-weight: bold;">
|
30
|
+
<%if task.has_access?(_site.user)%>
|
31
|
+
(<a href="javascript: comment_edit('<%=comment.id%>');"><%=_"edit"%></a>, <a href="javascript: if (confirm('<%=_"Do you want to delete this comment?"%>')){comment_delete('<%=comment.id%>');}"><%=_"delete"%></a>)
|
32
|
+
|
33
|
+
<%end%>
|
34
|
+
<%=comment.date_saved_str%>
|
35
|
+
</td>
|
36
|
+
</tr>
|
37
|
+
<tr>
|
38
|
+
<td colspan="3" style="border-top: 1px solid #cfcfcf; border-bottom: 1px solid #cfcfcf;">
|
39
|
+
<%=comment[:comment]%>
|
40
|
+
</td>
|
41
|
+
</tr>
|
42
|
+
</table>
|
43
|
+
</div>
|
44
|
+
<%
|
45
|
+
end
|
46
|
+
|
47
|
+
if comments.empty?
|
48
|
+
%>
|
49
|
+
<div class="error">
|
50
|
+
<%=_"No comments were found for this task."%>
|
51
|
+
</div>
|
52
|
+
<%
|
53
|
+
end
|
54
|
+
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
|
58
|
+
if _get["choice"] == "gettimelogs"
|
59
|
+
%>
|
60
|
+
<table class="list">
|
61
|
+
<thead>
|
62
|
+
<tr>
|
63
|
+
<th><%=_"ID"%></th>
|
64
|
+
<th><%=_"Hours"%></th>
|
65
|
+
<th><%=_"Date"%></th>
|
66
|
+
<th><%=_"User"%></th>
|
67
|
+
<th><%=_"Comment"%></th>
|
68
|
+
<%if _site.has_rank?("admin") and task.has_access?(_site.user)%>
|
69
|
+
<th><%=_"Delete"%></th>
|
70
|
+
<%end%>
|
71
|
+
</tr>
|
72
|
+
</thead>
|
73
|
+
<tbody>
|
74
|
+
<%
|
75
|
+
first = true
|
76
|
+
count_shown = 0
|
77
|
+
cur_date = Datet.new
|
78
|
+
|
79
|
+
tlogs.each do |tlog|
|
80
|
+
tlog_date = tlog.date
|
81
|
+
next if !_site.has_rank?("admin") and tlog_date.day == cur_date.day and tlog_date.month == cur_date.month and tlog_date.year == cur_date.year
|
82
|
+
|
83
|
+
dbt = Knj::Db::Dbtime.new(tlog[:time])
|
84
|
+
count_shown += 1
|
85
|
+
|
86
|
+
if !first
|
87
|
+
%>
|
88
|
+
<tr>
|
89
|
+
<td colspan="6"><hr size="1" color="#cfcfcf" /><td>
|
90
|
+
</tr>
|
91
|
+
<%
|
92
|
+
end
|
93
|
+
|
94
|
+
first = false if first
|
95
|
+
|
96
|
+
%>
|
97
|
+
<tr>
|
98
|
+
<td style="width: 50px;">
|
99
|
+
<%=tlog.html(:key => :id_localized)%>
|
100
|
+
</td>
|
101
|
+
<td style="width: 60px;">
|
102
|
+
<%=Knj::Locales.number_out(dbt.hours_total, 1)%>
|
103
|
+
</td>
|
104
|
+
<td class="nowrap" style="width: 90px;">
|
105
|
+
<%=tlog.date_str(:time => false)%>
|
106
|
+
</td>
|
107
|
+
<td style="width: 130px;">
|
108
|
+
<%=tlog.user_html%>
|
109
|
+
</td>
|
110
|
+
<td>
|
111
|
+
<%=tlog.comment_html%>
|
112
|
+
</td>
|
113
|
+
<%if _site.has_rank?("admin") and task.has_access?(_site.user)%>
|
114
|
+
<td style="width: 10%;">
|
115
|
+
(<a href="javascript: if (confirm('<%=_("Do you want to delete this timelog?")%>')){timelog_delete('<%=tlog.id%>');}"><%=_"delete"%></a>)
|
116
|
+
</td>
|
117
|
+
<%end%>
|
118
|
+
</tr>
|
119
|
+
<%
|
120
|
+
end
|
121
|
+
|
122
|
+
if count_shown <= 0
|
123
|
+
%>
|
124
|
+
<tr>
|
125
|
+
<td colspan="6" class="error">
|
126
|
+
<%=_("No timelogs were found.")%>
|
127
|
+
</td>
|
128
|
+
</tr>
|
129
|
+
<%
|
130
|
+
end
|
131
|
+
%>
|
132
|
+
</tbody>
|
133
|
+
</table>
|
134
|
+
<%
|
135
|
+
|
136
|
+
exit
|
137
|
+
end
|
138
|
+
|
139
|
+
if _get["choice"] == "getusers"
|
140
|
+
users = task.assigned_users
|
141
|
+
|
142
|
+
%>
|
143
|
+
<table class="list">
|
144
|
+
<thead>
|
145
|
+
<tr>
|
146
|
+
<th><%=_("User")%></th>
|
147
|
+
<th><%=_("Actions")%></th>
|
148
|
+
</tr>
|
149
|
+
</thead>
|
150
|
+
<tbody>
|
151
|
+
<%
|
152
|
+
users.each do |link|
|
153
|
+
%>
|
154
|
+
<tr>
|
155
|
+
<td>
|
156
|
+
<%=link.user.html%>
|
157
|
+
</td>
|
158
|
+
<td>
|
159
|
+
(<a href="javascript: if (confirm('<%=_("Do you want to remove this user from this task?")%>')){task_remove_assigned('<%=link.id%>');}"><%=_("remove")%></a>)
|
160
|
+
</td>
|
161
|
+
</tr>
|
162
|
+
<%
|
163
|
+
end
|
164
|
+
|
165
|
+
if users.empty?
|
166
|
+
%>
|
167
|
+
<tr>
|
168
|
+
<td colspan="2" class="error">
|
169
|
+
<%=_("No users has been assigned to this task.")%>
|
170
|
+
</td>
|
171
|
+
</tr>
|
172
|
+
<%
|
173
|
+
end
|
174
|
+
%>
|
175
|
+
</tbody>
|
176
|
+
</table>
|
177
|
+
<%
|
178
|
+
exit
|
179
|
+
end
|
180
|
+
|
181
|
+
if _get["choice"] == "assignuser"
|
182
|
+
begin
|
183
|
+
link = _ob.add(:Task_assigned_user, {
|
184
|
+
:task_id => task.id,
|
185
|
+
:user_id => _get["user_id"]
|
186
|
+
})
|
187
|
+
rescue RuntimeError => e
|
188
|
+
puts e.message
|
189
|
+
end
|
190
|
+
|
191
|
+
exit
|
192
|
+
end
|
193
|
+
|
194
|
+
if _get["choice"] == "getchecks"
|
195
|
+
checks = task.checks("orderby" => ["name", "id"])
|
196
|
+
|
197
|
+
checks.each do |check|
|
198
|
+
%>
|
199
|
+
<div>
|
200
|
+
<input type="checkbox" id="checheck_<%=check.id%>" name="checheck[<%=check.id%>]"<%if check[:checked].to_i == 1%> checked="checked"<%end%> onchange="task_check_set('<%=check.id%>', this.value);" />
|
201
|
+
<label for="checheck_<%=check.id%>"><%=check.name.html%></label>
|
202
|
+
|
203
|
+
(<a href="javascript: task_check_edit('<%=check.id%>');"><%=_("edit")%></a>, <a href="javascript: if (confirm('<%=_("Do you want to delete this check?")%>')){task_check_delete('<%=check.id%>');}"><%=_"delete"%></a>)
|
204
|
+
</div>
|
205
|
+
<%
|
206
|
+
|
207
|
+
if check[:descr].to_s.length > 0
|
208
|
+
%>
|
209
|
+
<div class="tdd">
|
210
|
+
<%=Php4r.nl2br(check[:descr].html)%>
|
211
|
+
</div>
|
212
|
+
<%
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
if checks.empty?
|
217
|
+
%>
|
218
|
+
<div class="error">
|
219
|
+
<%=_("No checks has been added for this task.")%>
|
220
|
+
</div>
|
221
|
+
<%
|
222
|
+
end
|
223
|
+
|
224
|
+
exit
|
225
|
+
end
|
226
|
+
|
227
|
+
if _get["choice"] == "addtolist"
|
228
|
+
_ob.add(:User_task_list_link, {
|
229
|
+
:task_id => task.id,
|
230
|
+
:user_id => _site.user.id
|
231
|
+
})
|
232
|
+
_hb.redirect("/?show=task_show&task_id=#{task.id}")
|
233
|
+
elsif _get["choice"] == "removefromlist"
|
234
|
+
_ob.list(:User_task_list_link, {
|
235
|
+
"task" => task,
|
236
|
+
"user" => _site.user
|
237
|
+
}) do |link|
|
238
|
+
_ob.delete(link)
|
239
|
+
end
|
240
|
+
|
241
|
+
_hb.redirect("/?show=task_show&task_id=#{task.id}")
|
242
|
+
end
|
243
|
+
|
244
|
+
print _site.header(sprintf(_("Show task: %s."), task.name.html))
|
245
|
+
%>
|
246
|
+
|
247
|
+
<div style="padding-bottom: 15px;">
|
248
|
+
<input type="button" value="<%=_"Edit task"%>" onclick="location.href='?show=task_edit&task_id=<%=task.id%>';" />
|
249
|
+
|
250
|
+
<%
|
251
|
+
task_link = _ob.get_by(:User_task_list_link, {
|
252
|
+
"user" => _site.user,
|
253
|
+
"task" => task
|
254
|
+
})
|
255
|
+
|
256
|
+
if task_link
|
257
|
+
%>
|
258
|
+
<input type="button" value="<%=_"Remove from list"%>" onclick="location.href='/?show=task_show&task_id=<%=task.id%>&choice=removefromlist';" />
|
259
|
+
<%
|
260
|
+
else
|
261
|
+
%>
|
262
|
+
<input type="button" value="<%=_"Add to list"%>" onclick="location.href='/?show=task_show&task_id=<%=task.id%>&choice=addtolist';" />
|
263
|
+
<%
|
264
|
+
end
|
265
|
+
%>
|
266
|
+
</div>
|
267
|
+
|
268
|
+
<div style="padding-bottom: 15px;">
|
269
|
+
<table style="width: 100%;" cellspacing="0" cellpadding="0">
|
270
|
+
<tr>
|
271
|
+
<td style="vertical-align: top; width: 60%;">
|
272
|
+
<%=_site.boxt(_("Task"))%>
|
273
|
+
<table class="form">
|
274
|
+
<%
|
275
|
+
print Knj::Web.inputs([{
|
276
|
+
:title => _("Status"),
|
277
|
+
:type => :info,
|
278
|
+
:value => _ob.static(:Task, :status_opts)[task[:status].to_sym],
|
279
|
+
:descr => _("The current status of the task.")
|
280
|
+
},{
|
281
|
+
:title => _("Type"),
|
282
|
+
:type => :info,
|
283
|
+
:value => _ob.static(:Task, :type_opts)[task[:type].to_sym],
|
284
|
+
:descr => _("The type of task this is.")
|
285
|
+
},{
|
286
|
+
:title => _("Date"),
|
287
|
+
:type => :info,
|
288
|
+
:value => task.date_added_str(:time => false),
|
289
|
+
:descr => _("The date this task was added.")
|
290
|
+
},{
|
291
|
+
:title => _("Project"),
|
292
|
+
:type => :info,
|
293
|
+
:value => task.project_html,
|
294
|
+
:descr => _("The project this task is created under.")
|
295
|
+
},{
|
296
|
+
:title => _("Author"),
|
297
|
+
:type => :info,
|
298
|
+
:value => task.user_html,
|
299
|
+
:descr => _("The user that created this task.")
|
300
|
+
},{
|
301
|
+
:title => _("Priority"),
|
302
|
+
:type => :info,
|
303
|
+
:value => _hb.num(task[:priority], 0),
|
304
|
+
:descr => _("The priority of the task. 10 as most important and 1 as least important.")
|
305
|
+
}])
|
306
|
+
%>
|
307
|
+
</table>
|
308
|
+
<%=_site.boxb%>
|
309
|
+
|
310
|
+
<br />
|
311
|
+
|
312
|
+
<%=_site.boxt(_("Description"))%>
|
313
|
+
<%
|
314
|
+
descr = task[:descr]
|
315
|
+
require "/usr/share/fckeditor/fckeditor.rb"
|
316
|
+
|
317
|
+
if FCKeditor.is_null?(descr)
|
318
|
+
%>
|
319
|
+
<div class="error">
|
320
|
+
<%=_("No description has been written for this task.")%>
|
321
|
+
</div>
|
322
|
+
<%
|
323
|
+
else
|
324
|
+
print descr
|
325
|
+
end
|
326
|
+
%>
|
327
|
+
<%=_site.boxb%>
|
328
|
+
</td>
|
329
|
+
<td style="vertical-align: top; padding-left: 15px;">
|
330
|
+
<%=_site.boxt(_("Assigned users"))%>
|
331
|
+
<div style="padding-bottom: 10px;">
|
332
|
+
<input type="button" value="<%=_("Assign a user")%>" onclick="modal({title: '<%=_"Assign user to task"%>', url: 'clean.rhtml?show=user_search&ajaxsearch=true&not_in_task_id=<%=task.id%>&jscallback=task_show_assign_user_choose'});" />
|
333
|
+
</div>
|
334
|
+
|
335
|
+
<div id="divusers">
|
336
|
+
<div class="error"><%=_"Loading - please wait..."%></div>
|
337
|
+
</div>
|
338
|
+
<%=_site.boxb%>
|
339
|
+
|
340
|
+
<br />
|
341
|
+
|
342
|
+
<%=_site.boxt(_("Checklist"))%>
|
343
|
+
<div style="padding-bottom: 15px;">
|
344
|
+
<input type="button" value="<%=_("Add new check")%>" onclick="modal({title: '<%=_"Add new check"%>', url: 'clean.rhtml?show=task_check_edit&task_id=<%=task.id%>'});" />
|
345
|
+
</div>
|
346
|
+
|
347
|
+
<div id="divchecks">
|
348
|
+
<div class="error"><%=_("Loading - please wait...")%></div>
|
349
|
+
</div>
|
350
|
+
<%=_site.boxb%>
|
351
|
+
</td>
|
352
|
+
</tr>
|
353
|
+
</table>
|
354
|
+
|
355
|
+
<div style="clear: both;"></div>
|
356
|
+
</div>
|
357
|
+
|
358
|
+
<div style="padding-bottom: 15px;">
|
359
|
+
<%=_site.boxt(_("Comments"))%>
|
360
|
+
<div style="padding-bottom: 15px;">
|
361
|
+
<input type="button" value="<%=_("Add new")%>" onclick="modal({title: '<%=_"Add new comment"%>', height: '540px', url: 'clean.rhtml?show=comment_edit&object_class=Task&object_id=<%=task.id%>'});" />
|
362
|
+
</div>
|
363
|
+
|
364
|
+
<div id="divcomments">
|
365
|
+
<div class="error"><%=_"Loading - please wait..."%></div>
|
366
|
+
</div>
|
367
|
+
|
368
|
+
<div>
|
369
|
+
<input type="button" value="<%=_("Add new")%>" onclick="modal({title: '<%=_"Add new comment"%>', height: '540px', url: 'clean.rhtml?show=comment_edit&object_class=Task&object_id=<%=task.id%>'});" />
|
370
|
+
</div>
|
371
|
+
<%=_site.boxb%>
|
372
|
+
</div>
|
373
|
+
|
374
|
+
<%=_site.boxt(_("Timelogs"))%>
|
375
|
+
<div style="padding-bottom: 15px;">
|
376
|
+
<input type="button" value="<%=_("Add new")%>" onclick="timelog_add('<%=task.id%>');" />
|
377
|
+
</div>
|
378
|
+
|
379
|
+
<div id="divtimelogs">
|
380
|
+
<div class="error"><%=_"Loading - please wait..."%></div>
|
381
|
+
</div>
|
382
|
+
<%=_site.boxb%>
|
383
|
+
|
384
|
+
<script type="text/javascript">
|
385
|
+
events.connect("do_comments_update", function(){
|
386
|
+
task_show_comments_update();
|
387
|
+
});
|
388
|
+
|
389
|
+
events.connect("do_timelogs_update", function(){
|
390
|
+
task_show_timelogs_update();
|
391
|
+
});
|
392
|
+
|
393
|
+
events.connect("do_task_assigned_users_update", function(){
|
394
|
+
task_show_users_update();
|
395
|
+
});
|
396
|
+
|
397
|
+
events.connect("do_task_check_update", function(){
|
398
|
+
task_show_checks_update();
|
399
|
+
});
|
400
|
+
|
401
|
+
function task_show_comments_update(){
|
402
|
+
$.ajax({type: "GET", url: "clean.rhtml?show=task_show&task_id=<%=task.id%>&choice=getcomments", async: true, cache: false, complete: function(data){
|
403
|
+
$("#divcomments").slideUp("fast", function(){
|
404
|
+
$("#divcomments").html(data.responseText);
|
405
|
+
$("#divcomments").slideDown("fast");
|
406
|
+
});
|
407
|
+
}});
|
408
|
+
}
|
409
|
+
|
410
|
+
function task_show_timelogs_update(){
|
411
|
+
$.ajax({type: "GET", url: "clean.rhtml?show=task_show&task_id=<%=task.id%>&choice=gettimelogs", async: true, cache: false, complete: function(data){
|
412
|
+
$("#divtimelogs").slideUp("fast", function(){
|
413
|
+
$("#divtimelogs").html(data.responseText);
|
414
|
+
$("#divtimelogs").slideDown("fast");
|
415
|
+
});
|
416
|
+
}});
|
417
|
+
}
|
418
|
+
|
419
|
+
function task_show_users_update(){
|
420
|
+
$.ajax({type: "GET", url: "clean.rhtml?show=task_show&task_id=<%=task.id%>&choice=getusers", async: true, cache: false, complete: function(data){
|
421
|
+
$("#divusers").slideUp("fast", function(){
|
422
|
+
$("#divusers").html(data.responseText);
|
423
|
+
$("#divusers").slideDown("fast");
|
424
|
+
});
|
425
|
+
}});
|
426
|
+
}
|
427
|
+
|
428
|
+
function task_show_assign_user_choose(user_id){
|
429
|
+
$.ajax({type: "GET", url: "clean.rhtml?show=task_show&task_id=<%=task.id%>&choice=assignuser&user_id=" + user_id, async: true, cache: false, complete: function(data){
|
430
|
+
if (data.responseText.length > 0){
|
431
|
+
alert(data.responseText);
|
432
|
+
}
|
433
|
+
|
434
|
+
task_show_users_update();
|
435
|
+
modal_close();
|
436
|
+
}});
|
437
|
+
}
|
438
|
+
|
439
|
+
function task_show_checks_update(){
|
440
|
+
$.ajax({type: "GET", url: "clean.rhtml?show=task_show&task_id=<%=task.id%>&choice=getchecks", async: true, cache: false, complete: function(data){
|
441
|
+
$("#divchecks").slideUp("fast", function(){
|
442
|
+
$("#divchecks").html(data.responseText);
|
443
|
+
$("#divchecks").slideDown("fast");
|
444
|
+
});
|
445
|
+
}});
|
446
|
+
}
|
447
|
+
|
448
|
+
$(document).ready(function(){
|
449
|
+
task_show_comments_update();
|
450
|
+
task_show_timelogs_update();
|
451
|
+
task_show_users_update();
|
452
|
+
task_show_checks_update();
|
453
|
+
});
|
454
|
+
</script>
|