fs-ticket 0.0.0 → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/render.rb +1 -0
- data/lib/ticket.rb +19 -3
- data/lib/view/add-ticket-view.rb +4 -4
- data/lib/view/add-ticket-view.rb~ +129 -0
- data/lib/view/edit-ticket-view.rb +155 -0
- data/lib/view/edit-ticket-view.rb~ +155 -0
- data/lib/view/report-view.rb +1 -1
- data/lib/view/report-view.rb~ +170 -0
- data/lib/view/ticket-view.rb +21 -3
- data/lib/view/ticket-view.rb~ +98 -0
- data/lib/widget/text-field-widget.rb +2 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e61f73a9d7829488435431894b0c726b5206df2
|
4
|
+
data.tar.gz: f7f457a9174d871a59fdfb4d59a1fe888bbd1301
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c73ddb25eafc4c972febdc33d9a5fba94f83cdcac99bf6f81ea79f99e078c5ff4b31e719237052816b25a42f90a6a3b0b7476679b5de5cf39ff41d00ffe9ca5
|
7
|
+
data.tar.gz: 06ac829e5ac908c93c8d9479fe2794665fd1d8341c00fb07c6aa89ebe003ff2cb2c9a3ef56dedf6d36bbec77c8c8514d1255458a260281fb251c34d62b2f2b4c
|
data/lib/render.rb
CHANGED
data/lib/ticket.rb
CHANGED
@@ -2,9 +2,7 @@ class Ticket
|
|
2
2
|
def initialize(database, id)
|
3
3
|
@db = database
|
4
4
|
@ticketid = id
|
5
|
-
|
6
|
-
@status = nil
|
7
|
-
@comments = nil
|
5
|
+
refresh
|
8
6
|
end
|
9
7
|
|
10
8
|
def select(field)
|
@@ -60,6 +58,10 @@ class Ticket
|
|
60
58
|
def priority
|
61
59
|
@priority ||= select("priority")
|
62
60
|
end
|
61
|
+
|
62
|
+
def resolution
|
63
|
+
@resolution ||= select("resolution")
|
64
|
+
end
|
63
65
|
|
64
66
|
|
65
67
|
def resolve
|
@@ -69,6 +71,20 @@ class Ticket
|
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
74
|
+
def id
|
75
|
+
@ticketid
|
76
|
+
end
|
77
|
+
|
78
|
+
def refresh
|
79
|
+
@title = nil
|
80
|
+
@status = nil
|
81
|
+
@type = nil
|
82
|
+
@subsystem = nil
|
83
|
+
@priority = nil
|
84
|
+
@resolution = nil
|
85
|
+
@comments = nil
|
86
|
+
end
|
87
|
+
|
72
88
|
def match(regex)
|
73
89
|
(comments && comments.match(regex)) || (title && title.match(regex))
|
74
90
|
end
|
data/lib/view/add-ticket-view.rb
CHANGED
@@ -19,7 +19,7 @@ class AddTicketView
|
|
19
19
|
@screen.clear
|
20
20
|
@screen.setpos(0,0)
|
21
21
|
@screen.attron(Curses.color_pair(1));
|
22
|
-
@screen.addstr("Issue Creation")
|
22
|
+
@screen.addstr("Issue Creation - [e]dit (with vim)")
|
23
23
|
@screen.attroff(Curses.color_pair(1));
|
24
24
|
|
25
25
|
|
@@ -64,9 +64,6 @@ class AddTicketView
|
|
64
64
|
when ?\t, 9
|
65
65
|
changeActive (@active_id + 1) % @widgets.length
|
66
66
|
display
|
67
|
-
when ?e
|
68
|
-
edit
|
69
|
-
display
|
70
67
|
else
|
71
68
|
if(!@widgets[@active_id].handle(c))
|
72
69
|
if(c == Curses::KEY_UP)
|
@@ -75,6 +72,9 @@ class AddTicketView
|
|
75
72
|
elsif(c == Curses::KEY_DOWN)
|
76
73
|
changeActive @active_id + 1
|
77
74
|
display
|
75
|
+
elsif(c == ?e)
|
76
|
+
edit
|
77
|
+
display
|
78
78
|
else
|
79
79
|
@screen.setpos(0,0)
|
80
80
|
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
@@ -0,0 +1,129 @@
|
|
1
|
+
class AddTicketView
|
2
|
+
def initialize(screen)
|
3
|
+
@screen = screen
|
4
|
+
@props = Hash.new
|
5
|
+
@title = TextLineWidget.new(@screen, "", 11, 1, 30)
|
6
|
+
@priort = DropdownWidget.new(@screen, "Zero", 11, 2, 30)
|
7
|
+
@type = DropdownWidget.new(@screen, "Unclassified", 11, 3, 30)
|
8
|
+
@desc = TextFieldWidget.new(@screen, "", 0, 5, 78, 14)
|
9
|
+
@cancel = ButtonWidget.new(@screen, "Cancel", 20, 20)
|
10
|
+
@submit = ButtonWidget.new(@screen, "Submit", 0, 20)
|
11
|
+
@priort.options = %w{Zero Low Medium High Immediate}
|
12
|
+
@type.options = %w{Incident Code_Defect Build_Problem Documentation Feature_Request}
|
13
|
+
@widgets = [@title, @priort, @type, @desc, @submit, @cancel]
|
14
|
+
@title.active = true
|
15
|
+
@active_id = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def display
|
19
|
+
@screen.clear
|
20
|
+
@screen.setpos(0,0)
|
21
|
+
@screen.attron(Curses.color_pair(1));
|
22
|
+
@screen.addstr("Issue Creation - [e]dit (with vim)")
|
23
|
+
@screen.attroff(Curses.color_pair(1));
|
24
|
+
|
25
|
+
|
26
|
+
@screen.setpos(1,0)
|
27
|
+
@screen.addstr("Title:")
|
28
|
+
@screen.setpos(2,0)
|
29
|
+
@screen.addstr("Priority:")
|
30
|
+
@screen.setpos(3,0)
|
31
|
+
@screen.addstr("Type:")
|
32
|
+
@screen.setpos(4,0)
|
33
|
+
@screen.addstr("Description:")
|
34
|
+
|
35
|
+
ln = 6
|
36
|
+
@widgets.each_with_index do |w, idx|
|
37
|
+
if(idx != @active_id)
|
38
|
+
w.draw
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#Draw the active widget last as it might have an overlay
|
43
|
+
@widgets[@active_id].draw
|
44
|
+
end
|
45
|
+
|
46
|
+
def changeActive(a)
|
47
|
+
a = [a,0].max
|
48
|
+
a = [a,@widgets.length-1].min
|
49
|
+
|
50
|
+
if(@active_id != a)
|
51
|
+
@widgets[@active_id].active = false
|
52
|
+
@active_id = a
|
53
|
+
@widgets[@active_id].active = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def interact
|
58
|
+
while true
|
59
|
+
result = true
|
60
|
+
c = Curses.getch
|
61
|
+
case c
|
62
|
+
when 27
|
63
|
+
break
|
64
|
+
when ?\t, 9
|
65
|
+
changeActive (@active_id + 1) % @widgets.length
|
66
|
+
display
|
67
|
+
else
|
68
|
+
if(!@widgets[@active_id].handle(c))
|
69
|
+
if(c == Curses::KEY_UP)
|
70
|
+
changeActive @active_id - 1
|
71
|
+
display
|
72
|
+
elsif(c == Curses::KEY_DOWN)
|
73
|
+
changeActive @active_id + 1
|
74
|
+
display
|
75
|
+
elsif(c == ?e)
|
76
|
+
edit
|
77
|
+
display
|
78
|
+
else
|
79
|
+
@screen.setpos(0,0)
|
80
|
+
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
81
|
+
end
|
82
|
+
else
|
83
|
+
if((c == "\n" || c == 13) && @submit == @widgets[@active_id])
|
84
|
+
`fossil ticket add title '#{@title.value}' priority '#{@priort.value}' type '#{@type.value}' icomment '#{@desc.value}' status Open`
|
85
|
+
return :do_refresh
|
86
|
+
elsif((c == "\n" || c == 13) && @cancel == @widgets[@active_id])
|
87
|
+
break
|
88
|
+
else
|
89
|
+
display
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
@screen.setpos(0,0)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def edit
|
98
|
+
tmp = File.open("fs-ticket-edit.yaml", "w+")
|
99
|
+
tmp.puts({"title" => @title.value,
|
100
|
+
"priority" => @priort.value,
|
101
|
+
"type" => @type.value,
|
102
|
+
"description" => @desc.value}.to_yaml)
|
103
|
+
tmp.close
|
104
|
+
|
105
|
+
system("vim fs-ticket-edit.yaml")
|
106
|
+
|
107
|
+
#Restore curses options
|
108
|
+
Curses.raw
|
109
|
+
Curses.nonl
|
110
|
+
#Curses.cbreak
|
111
|
+
Curses.noecho
|
112
|
+
Curses.curs_set(0)
|
113
|
+
@screen.scrollok(true)
|
114
|
+
@screen.keypad(true)
|
115
|
+
|
116
|
+
begin
|
117
|
+
tmp = File.open("fs-ticket-edit.yaml", "r")
|
118
|
+
yy = YAML.load(tmp.read)
|
119
|
+
tmp.close
|
120
|
+
@title.value = yy["title"]
|
121
|
+
@priort.value = yy["priority"]
|
122
|
+
@type.value = yy["type"]
|
123
|
+
@desc.value = yy["description"]
|
124
|
+
|
125
|
+
#Later these editing errors should be handled correctly
|
126
|
+
#rescue Exception=>e
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
class EditTicketView
|
2
|
+
attr_accessor :status
|
3
|
+
|
4
|
+
def initialize(screen, ticket)
|
5
|
+
@screen = screen
|
6
|
+
@ticket = ticket
|
7
|
+
@props = Hash.new
|
8
|
+
@title = TextLineWidget.new(@screen, @ticket.title, 11, 1, 30)
|
9
|
+
@priort = DropdownWidget.new(@screen, @ticket.priority, 11, 2, 30)
|
10
|
+
@type = DropdownWidget.new(@screen, @ticket.type, 11, 3, 30)
|
11
|
+
@status = DropdownWidget.new(@screen, @ticket.status, 11, 4, 30)
|
12
|
+
@resolv = DropdownWidget.new(@screen, @ticket.resolution, 11, 5, 30)
|
13
|
+
@desc = TextFieldWidget.new(@screen, "", 0, 7, 78, 12)
|
14
|
+
@cancel = ButtonWidget.new(@screen, "Cancel", 20, 20)
|
15
|
+
@submit = ButtonWidget.new(@screen, "Submit", 0, 20)
|
16
|
+
@priort.options = %w{Zero Low Medium High Immediate}
|
17
|
+
@type.options = %w{Incident Code_Defect Build_Problem Documentation Feature_Request}
|
18
|
+
@status.options = %w{Open Verified Review Deferred Fixed Tested Closed}
|
19
|
+
@resolv.options= %w{Open Fixed Rejected Workaround Unable_To_Reproduce Works_As_Designed External_Bug Not_A_Bug Duplicate Overcome_By_Events Drive_By_Patch Misconfiguration}
|
20
|
+
|
21
|
+
@widgets = [@title, @priort, @type, @status, @resolv, @desc, @submit, @cancel]
|
22
|
+
@title.active = true
|
23
|
+
@active_id = 0
|
24
|
+
|
25
|
+
@title.value = @ticket.title
|
26
|
+
@priort.value = @ticket.priority
|
27
|
+
@type.value = @ticket.type
|
28
|
+
@status.value = @ticket.status
|
29
|
+
@resolv.value = @ticket.resolution
|
30
|
+
end
|
31
|
+
|
32
|
+
def display
|
33
|
+
@screen.clear
|
34
|
+
@screen.setpos(0,0)
|
35
|
+
@screen.attron(Curses.color_pair(1));
|
36
|
+
@screen.addstr("Issue Edit Window - [e]dit (in vim)")
|
37
|
+
@screen.attroff(Curses.color_pair(1));
|
38
|
+
|
39
|
+
|
40
|
+
@screen.setpos(1,0)
|
41
|
+
@screen.addstr("Title:")
|
42
|
+
@screen.setpos(2,0)
|
43
|
+
@screen.addstr("Priority:")
|
44
|
+
@screen.setpos(3,0)
|
45
|
+
@screen.addstr("Type:")
|
46
|
+
@screen.setpos(4,0)
|
47
|
+
@screen.addstr("Status:")
|
48
|
+
@screen.setpos(5,0)
|
49
|
+
@screen.addstr("Resolution:")
|
50
|
+
@screen.setpos(6,0)
|
51
|
+
@screen.addstr("Comment:")
|
52
|
+
|
53
|
+
ln = 7
|
54
|
+
@widgets.each_with_index do |w, idx|
|
55
|
+
if(idx != @active_id)
|
56
|
+
w.draw
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#Draw the active widget last as it might have an overlay
|
61
|
+
@widgets[@active_id].draw
|
62
|
+
end
|
63
|
+
|
64
|
+
def changeActive(a)
|
65
|
+
a = [a,0].max
|
66
|
+
a = [a,@widgets.length-1].min
|
67
|
+
|
68
|
+
if(@active_id != a)
|
69
|
+
@widgets[@active_id].active = false
|
70
|
+
@active_id = a
|
71
|
+
@widgets[@active_id].active = true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def interact
|
76
|
+
while true
|
77
|
+
result = true
|
78
|
+
c = Curses.getch
|
79
|
+
case c
|
80
|
+
when 27
|
81
|
+
break
|
82
|
+
when ?\t, 9
|
83
|
+
changeActive (@active_id + 1) % @widgets.length
|
84
|
+
display
|
85
|
+
else
|
86
|
+
if(!@widgets[@active_id].handle(c))
|
87
|
+
if(c == Curses::KEY_UP)
|
88
|
+
changeActive @active_id - 1
|
89
|
+
display
|
90
|
+
elsif(c == Curses::KEY_DOWN)
|
91
|
+
changeActive @active_id + 1
|
92
|
+
display
|
93
|
+
elsif(c == ?e)
|
94
|
+
edit
|
95
|
+
display
|
96
|
+
else
|
97
|
+
@screen.setpos(0,0)
|
98
|
+
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
99
|
+
end
|
100
|
+
else
|
101
|
+
if((c == "\n" || c == 13) && @submit == @widgets[@active_id])
|
102
|
+
`fossil ticket set #{@ticket.id} title '#{@title.value}' priority '#{@priort.value}' type '#{@type.value}' status '#{@status.value}' resolution '#{@resolv.value}'`
|
103
|
+
if(!@desc.value.empty?)
|
104
|
+
`fossil ticket set #{@ticket.id} icomment '#{@desc.value}'`
|
105
|
+
end
|
106
|
+
@ticket.refresh
|
107
|
+
return :do_refresh
|
108
|
+
elsif((c == "\n" || c == 13) && @cancel == @widgets[@active_id])
|
109
|
+
break
|
110
|
+
else
|
111
|
+
display
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
@screen.setpos(0,0)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def edit
|
120
|
+
tmp = File.open("fs-ticket-edit.yaml", "w+")
|
121
|
+
tmp.puts({"title" => @title.value,
|
122
|
+
"priority" => @priort.value,
|
123
|
+
"type" => @type.value,
|
124
|
+
"status" => @status.value,
|
125
|
+
"resolution" => @resolv.value,
|
126
|
+
"comment" => @desc.value}.to_yaml)
|
127
|
+
tmp.close
|
128
|
+
|
129
|
+
system("vim fs-ticket-edit.yaml")
|
130
|
+
|
131
|
+
#Restore curses options
|
132
|
+
Curses.raw
|
133
|
+
Curses.nonl
|
134
|
+
#Curses.cbreak
|
135
|
+
Curses.noecho
|
136
|
+
Curses.curs_set(0)
|
137
|
+
@screen.scrollok(true)
|
138
|
+
@screen.keypad(true)
|
139
|
+
|
140
|
+
begin
|
141
|
+
tmp = File.open("fs-ticket-edit.yaml", "r")
|
142
|
+
yy = YAML.load(tmp.read)
|
143
|
+
tmp.close
|
144
|
+
@title.value = yy["title"]
|
145
|
+
@priort.value = yy["priority"]
|
146
|
+
@type.value = yy["type"]
|
147
|
+
@status.value = yy["status"]
|
148
|
+
@resolv.value = yy["resolution"]
|
149
|
+
@desc.value = yy["description"]
|
150
|
+
|
151
|
+
#Later these editing errors should be handled correctly
|
152
|
+
#rescue Exception=>e
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
class EditTicketView
|
2
|
+
attr_accessor :status
|
3
|
+
|
4
|
+
def initialize(screen, ticket)
|
5
|
+
@screen = screen
|
6
|
+
@ticket = ticket
|
7
|
+
@props = Hash.new
|
8
|
+
@title = TextLineWidget.new(@screen, @ticket.title, 11, 1, 30)
|
9
|
+
@priort = DropdownWidget.new(@screen, @ticket.priority, 11, 2, 30)
|
10
|
+
@type = DropdownWidget.new(@screen, @ticket.type, 11, 3, 30)
|
11
|
+
@status = DropdownWidget.new(@screen, @ticket.status, 11, 4, 30)
|
12
|
+
@resolv = DropdownWidget.new(@screen, @ticket.resolution, 11, 5, 30)
|
13
|
+
@desc = TextFieldWidget.new(@screen, "", 0, 7, 78, 12)
|
14
|
+
@cancel = ButtonWidget.new(@screen, "Cancel", 20, 20)
|
15
|
+
@submit = ButtonWidget.new(@screen, "Submit", 0, 20)
|
16
|
+
@priort.options = %w{Zero Low Medium High Immediate}
|
17
|
+
@type.options = %w{Incident Code_Defect Build_Problem Documentation Feature_Request}
|
18
|
+
@status.options = %w{Open Verified Review Deferred Fixed Tested Closed}
|
19
|
+
@resolv.options= %w{Open Fixed Rejected Workaround Unable_To_Reproduce Works_As_Designed External_Bug Not_A_Bug Duplicate Overcome_By_Events Drive_By_Patch Misconfiguration}
|
20
|
+
|
21
|
+
@widgets = [@title, @priort, @type, @status, @resolv, @desc, @submit, @cancel]
|
22
|
+
@title.active = true
|
23
|
+
@active_id = 0
|
24
|
+
|
25
|
+
@title.value = @ticket.title
|
26
|
+
@priort.value = @ticket.priority
|
27
|
+
@type.value = @ticket.type
|
28
|
+
@status.value = @ticket.status
|
29
|
+
@resolv.value = @ticket.resolution
|
30
|
+
end
|
31
|
+
|
32
|
+
def display
|
33
|
+
@screen.clear
|
34
|
+
@screen.setpos(0,0)
|
35
|
+
@screen.attron(Curses.color_pair(1));
|
36
|
+
@screen.addstr("Issue Edit Window - [e]dit (in vim)")
|
37
|
+
@screen.attroff(Curses.color_pair(1));
|
38
|
+
|
39
|
+
|
40
|
+
@screen.setpos(1,0)
|
41
|
+
@screen.addstr("Title:")
|
42
|
+
@screen.setpos(2,0)
|
43
|
+
@screen.addstr("Priority:")
|
44
|
+
@screen.setpos(3,0)
|
45
|
+
@screen.addstr("Type:")
|
46
|
+
@screen.setpos(4,0)
|
47
|
+
@screen.addstr("Status:")
|
48
|
+
@screen.setpos(5,0)
|
49
|
+
@screen.addstr("Resolution:")
|
50
|
+
@screen.setpos(6,0)
|
51
|
+
@screen.addstr("Comment:")
|
52
|
+
|
53
|
+
ln = 7
|
54
|
+
@widgets.each_with_index do |w, idx|
|
55
|
+
if(idx != @active_id)
|
56
|
+
w.draw
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#Draw the active widget last as it might have an overlay
|
61
|
+
@widgets[@active_id].draw
|
62
|
+
end
|
63
|
+
|
64
|
+
def changeActive(a)
|
65
|
+
a = [a,0].max
|
66
|
+
a = [a,@widgets.length-1].min
|
67
|
+
|
68
|
+
if(@active_id != a)
|
69
|
+
@widgets[@active_id].active = false
|
70
|
+
@active_id = a
|
71
|
+
@widgets[@active_id].active = true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def interact
|
76
|
+
while true
|
77
|
+
result = true
|
78
|
+
c = Curses.getch
|
79
|
+
case c
|
80
|
+
when 27
|
81
|
+
break
|
82
|
+
when ?\t, 9
|
83
|
+
changeActive (@active_id + 1) % @widgets.length
|
84
|
+
display
|
85
|
+
else
|
86
|
+
if(!@widgets[@active_id].handle(c))
|
87
|
+
if(c == Curses::KEY_UP)
|
88
|
+
changeActive @active_id - 1
|
89
|
+
display
|
90
|
+
elsif(c == Curses::KEY_DOWN)
|
91
|
+
changeActive @active_id + 1
|
92
|
+
display
|
93
|
+
elsif(c == ?e)
|
94
|
+
edit
|
95
|
+
display
|
96
|
+
else
|
97
|
+
@screen.setpos(0,0)
|
98
|
+
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
99
|
+
end
|
100
|
+
else
|
101
|
+
if((c == "\n" || c == 13) && @submit == @widgets[@active_id])
|
102
|
+
`fossil ticket set #{@ticket.id} title '#{@title.value}' priority '#{@priort.value}' type '#{@type.value}' status '#{@status.value}' resolution '#{@resolv.value}'`
|
103
|
+
if(!@desc.value.empty?)
|
104
|
+
`fossil ticket set #{@ticket.id} icomment '#{@desc.value}'`
|
105
|
+
end
|
106
|
+
@ticket.refresh
|
107
|
+
return :do_refresh
|
108
|
+
elsif((c == "\n" || c == 13) && @cancel == @widgets[@active_id])
|
109
|
+
break
|
110
|
+
else
|
111
|
+
display
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
@screen.setpos(0,0)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def edit
|
120
|
+
tmp = File.open("fs-ticket-edit.yaml", "w+")
|
121
|
+
tmp.puts({"title" => @title.value,
|
122
|
+
"priority" => @priort.value,
|
123
|
+
"type" => @type.value,
|
124
|
+
"status" => @status.value,
|
125
|
+
"resolution" => @resolv.value,
|
126
|
+
"comment" => @desc.value}.to_yaml)
|
127
|
+
tmp.close
|
128
|
+
|
129
|
+
system("vim fs-ticket-edit.yaml")
|
130
|
+
|
131
|
+
#Restore curses options
|
132
|
+
Curses.raw
|
133
|
+
Curses.nonl
|
134
|
+
#Curses.cbreak
|
135
|
+
Curses.noecho
|
136
|
+
Curses.curs_set(0)
|
137
|
+
@screen.scrollok(true)
|
138
|
+
@screen.keypad(true)
|
139
|
+
|
140
|
+
begin
|
141
|
+
tmp = File.open("fs-ticket-edit.yaml", "r")
|
142
|
+
yy = YAML.load(tmp.read)
|
143
|
+
tmp.close
|
144
|
+
@title.value = yy["title"]
|
145
|
+
@priort.value = yy["priority"]
|
146
|
+
@type.value = yy["type"]
|
147
|
+
@status.value = yy["status"]
|
148
|
+
@resolv.value = yy["resolution"]
|
149
|
+
@desc.value = yy["description"]
|
150
|
+
|
151
|
+
#Later these editing errors should be handled correctly
|
152
|
+
#rescue Exception=>e
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/lib/view/report-view.rb
CHANGED
@@ -66,7 +66,7 @@ class ReportView
|
|
66
66
|
|
67
67
|
@screen.setpos(0,0)
|
68
68
|
@screen.attron(Curses.color_pair(1));
|
69
|
-
@screen.addstr("Issue Overview - [a]dd new issue, [t]oggle open issues, [q]uit")
|
69
|
+
@screen.addstr("Issue Overview - [a]dd new issue, [t]oggle open issues, [q]uit, [/]search")
|
70
70
|
@screen.attroff(Curses.color_pair(1));
|
71
71
|
|
72
72
|
start = 0
|
@@ -0,0 +1,170 @@
|
|
1
|
+
class ReportView
|
2
|
+
def initialize(screen, tickets, block)
|
3
|
+
@screen = screen
|
4
|
+
@mode = :all
|
5
|
+
@real_tickets = tickets
|
6
|
+
@tickets = tickets
|
7
|
+
@refresh = block
|
8
|
+
@highlight = 0
|
9
|
+
display_lines
|
10
|
+
end
|
11
|
+
|
12
|
+
def refresh
|
13
|
+
@real_tickets = @refresh.call
|
14
|
+
toggle_open_tickets
|
15
|
+
toggle_open_tickets
|
16
|
+
end
|
17
|
+
|
18
|
+
def toggle_open_tickets
|
19
|
+
@highlight = 0
|
20
|
+
if(@mode == :all)
|
21
|
+
@tickets = []
|
22
|
+
@real_tickets.each do |t|
|
23
|
+
if(t.status == "Open")
|
24
|
+
@tickets << t
|
25
|
+
end
|
26
|
+
end
|
27
|
+
@mode = :open
|
28
|
+
elsif(@mode == :open || @mode == :search)
|
29
|
+
@tickets = @real_tickets
|
30
|
+
@mode = :all
|
31
|
+
end
|
32
|
+
display_lines
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_search(term)
|
36
|
+
@highlight = 0
|
37
|
+
@tickets = []
|
38
|
+
@real_tickets.each do |t|
|
39
|
+
if(t.match term)
|
40
|
+
@tickets << t
|
41
|
+
end
|
42
|
+
end
|
43
|
+
@mode = :search
|
44
|
+
display_lines
|
45
|
+
end
|
46
|
+
|
47
|
+
def search
|
48
|
+
label = TextLineWidget.new(@screen, "search: ", 0, @screen.maxy-1, 40)
|
49
|
+
line = TextLineWidget.new(@screen, "", 10, @screen.maxy-1, 40)
|
50
|
+
label.draw
|
51
|
+
line.draw
|
52
|
+
while true
|
53
|
+
c = Curses.getch
|
54
|
+
if(c == "\n" || !line.handle(c))
|
55
|
+
run_search(line.value)
|
56
|
+
break
|
57
|
+
else
|
58
|
+
label.draw
|
59
|
+
line.draw
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def display_lines
|
65
|
+
@screen.clear
|
66
|
+
|
67
|
+
@screen.setpos(0,0)
|
68
|
+
@screen.attron(Curses.color_pair(1));
|
69
|
+
@screen.addstr("Issue Overview - [a]dd new issue, [t]oggle open issues, [q]uit")
|
70
|
+
@screen.attroff(Curses.color_pair(1));
|
71
|
+
|
72
|
+
start = 0
|
73
|
+
ylimit = @screen.maxy-1
|
74
|
+
upper = ylimit-1
|
75
|
+
if(@highlight >= ylimit)
|
76
|
+
start = ylimit*(@highlight/ylimit).to_i
|
77
|
+
upper = start + ylimit - 1
|
78
|
+
end
|
79
|
+
|
80
|
+
if(@tickets.empty?)
|
81
|
+
return
|
82
|
+
end
|
83
|
+
|
84
|
+
@tickets[start..upper].each_with_index{|tick, idx|
|
85
|
+
line = tick.title
|
86
|
+
line_id = idx+start
|
87
|
+
@screen.setpos(idx+1, 0)
|
88
|
+
@screen.addstr(line_id.to_s+".")
|
89
|
+
@screen.setpos(idx+1, 4)
|
90
|
+
if(tick.status)
|
91
|
+
@screen.addstr("["+tick.status[0]+"]")
|
92
|
+
end
|
93
|
+
@screen.setpos(idx+1, 9)
|
94
|
+
if(@highlight == line_id)
|
95
|
+
@screen.attron Curses::A_BOLD
|
96
|
+
@screen.addstr(line)
|
97
|
+
@screen.attroff Curses::A_BOLD
|
98
|
+
else
|
99
|
+
@screen.addstr(line)
|
100
|
+
end
|
101
|
+
}
|
102
|
+
@screen.setpos(0,0)
|
103
|
+
@screen.refresh
|
104
|
+
end
|
105
|
+
|
106
|
+
def scroll_up(draw=true)
|
107
|
+
if(@highlight > 0)
|
108
|
+
@highlight -= 1
|
109
|
+
display_lines if draw
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def scroll_down(draw=true)
|
114
|
+
if(@highlight < @tickets.length-1)
|
115
|
+
@highlight += 1
|
116
|
+
display_lines if draw
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def interact
|
121
|
+
while true
|
122
|
+
result = true
|
123
|
+
c = Curses.getch
|
124
|
+
case c
|
125
|
+
when ?t
|
126
|
+
toggle_open_tickets
|
127
|
+
when ?a
|
128
|
+
at = AddTicketView.new(@screen)
|
129
|
+
@screen.clear
|
130
|
+
at.display
|
131
|
+
ret = at.interact
|
132
|
+
if(ret == :do_refresh)
|
133
|
+
refresh
|
134
|
+
end
|
135
|
+
@screen.clear
|
136
|
+
display_lines
|
137
|
+
when Curses::KEY_DOWN, Curses::KEY_CTRL_N, ?j
|
138
|
+
result = scroll_down
|
139
|
+
when Curses::KEY_UP, Curses::KEY_CTRL_P, ?k
|
140
|
+
result = scroll_up
|
141
|
+
when Curses::KEY_NPAGE, ?\s # white space
|
142
|
+
for i in 0..(@screen.maxy - 2)
|
143
|
+
scroll_down(false)
|
144
|
+
end
|
145
|
+
display_lines
|
146
|
+
when Curses::KEY_PPAGE
|
147
|
+
for i in 0..(@screen.maxy - 2)
|
148
|
+
scroll_up(false)
|
149
|
+
end
|
150
|
+
display_lines
|
151
|
+
when Curses::KEY_RIGHT, Curses::KEY_ENTER, ?\n, 13
|
152
|
+
tv = TicketView.new(@screen, @tickets[@highlight])
|
153
|
+
@screen.clear
|
154
|
+
tv.display
|
155
|
+
ret = tv.interact
|
156
|
+
@screen.clear
|
157
|
+
display_lines
|
158
|
+
when "/"
|
159
|
+
search
|
160
|
+
when ?q
|
161
|
+
break
|
162
|
+
else
|
163
|
+
@screen.setpos(0,0)
|
164
|
+
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
165
|
+
end
|
166
|
+
@screen.setpos(0,0)
|
167
|
+
end
|
168
|
+
Curses.close_screen
|
169
|
+
end
|
170
|
+
end
|
data/lib/view/ticket-view.rb
CHANGED
@@ -10,7 +10,7 @@ class TicketView
|
|
10
10
|
@screen.clear
|
11
11
|
@screen.setpos(0,0)
|
12
12
|
@screen.attron(Curses.color_pair(1));
|
13
|
-
@screen.addstr("Issue Details - [f]ix [q]uit")
|
13
|
+
@screen.addstr("Issue Details - [f]ix, [e]dit, [q]uit")
|
14
14
|
@screen.attroff(Curses.color_pair(1));
|
15
15
|
|
16
16
|
|
@@ -35,6 +35,7 @@ class TicketView
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def interact
|
38
|
+
ret = nil
|
38
39
|
while true
|
39
40
|
result = true
|
40
41
|
c = Curses.getch
|
@@ -44,10 +45,26 @@ class TicketView
|
|
44
45
|
when ?q
|
45
46
|
break
|
46
47
|
when ?f
|
47
|
-
@ticket
|
48
|
+
et = EditTicketView.new(@screen, @ticket)
|
49
|
+
@screen.clear
|
50
|
+
if(et.status.value == "Open")
|
51
|
+
et.status.value = "Fixed"
|
52
|
+
end
|
53
|
+
et.display
|
54
|
+
tmp = et.interact
|
55
|
+
ret ||= tmp
|
56
|
+
@screen.clear
|
48
57
|
display
|
49
58
|
when ?e
|
50
|
-
|
59
|
+
et = EditTicketView.new(@screen, @ticket)
|
60
|
+
@screen.clear
|
61
|
+
if(et.status == "Open")
|
62
|
+
et.status = "Fixed"
|
63
|
+
end
|
64
|
+
et.display
|
65
|
+
tmp = et.interact
|
66
|
+
ret ||= tmp
|
67
|
+
@screen.clear
|
51
68
|
display
|
52
69
|
else
|
53
70
|
@screen.setpos(0,0)
|
@@ -55,6 +72,7 @@ class TicketView
|
|
55
72
|
end
|
56
73
|
@screen.setpos(0,0)
|
57
74
|
end
|
75
|
+
ret
|
58
76
|
end
|
59
77
|
|
60
78
|
def edit
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class TicketView
|
4
|
+
def initialize(screen, ticket)
|
5
|
+
@screen = screen
|
6
|
+
@ticket = ticket
|
7
|
+
end
|
8
|
+
|
9
|
+
def display
|
10
|
+
@screen.clear
|
11
|
+
@screen.setpos(0,0)
|
12
|
+
@screen.attron(Curses.color_pair(1));
|
13
|
+
@screen.addstr("Issue Details - [f]ix [q]uit")
|
14
|
+
@screen.attroff(Curses.color_pair(1));
|
15
|
+
|
16
|
+
|
17
|
+
@screen.setpos(1,0)
|
18
|
+
@screen.addstr("Title: #{@ticket.title}")
|
19
|
+
@screen.setpos(2,0)
|
20
|
+
@screen.addstr("Status: #{@ticket.status}")
|
21
|
+
@screen.setpos(3,0)
|
22
|
+
@screen.addstr("Priority: #{@ticket.priority}")
|
23
|
+
@screen.setpos(4,0)
|
24
|
+
@screen.addstr("Type: #{@ticket.type}")
|
25
|
+
@screen.setpos(5,0)
|
26
|
+
@screen.addstr("Subsystem: #{@ticket.subsystem}")
|
27
|
+
@screen.setpos(6,0)
|
28
|
+
@screen.addstr("Comments:")
|
29
|
+
ln = 7
|
30
|
+
@ticket.comments.split("\n").each do |l|
|
31
|
+
@screen.setpos(ln,0)
|
32
|
+
@screen.addstr(l)
|
33
|
+
ln += 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def interact
|
38
|
+
ret = nil
|
39
|
+
while true
|
40
|
+
result = true
|
41
|
+
c = Curses.getch
|
42
|
+
case c
|
43
|
+
when Curses::KEY_LEFT
|
44
|
+
break
|
45
|
+
when ?q
|
46
|
+
break
|
47
|
+
when ?f
|
48
|
+
et = EditTicketView.new(@screen, @ticket)
|
49
|
+
@screen.clear
|
50
|
+
if(et.status.value == "Open")
|
51
|
+
et.status.value = "Fixed"
|
52
|
+
end
|
53
|
+
et.display
|
54
|
+
tmp = et.interact
|
55
|
+
ret ||= tmp
|
56
|
+
@screen.clear
|
57
|
+
display
|
58
|
+
when ?e
|
59
|
+
et = EditTicketView.new(@screen, @ticket)
|
60
|
+
@screen.clear
|
61
|
+
if(et.status == "Open")
|
62
|
+
et.status = "Fixed"
|
63
|
+
end
|
64
|
+
et.display
|
65
|
+
tmp = et.interact
|
66
|
+
ret ||= tmp
|
67
|
+
@screen.clear
|
68
|
+
display
|
69
|
+
else
|
70
|
+
@screen.setpos(0,0)
|
71
|
+
@screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
|
72
|
+
end
|
73
|
+
@screen.setpos(0,0)
|
74
|
+
end
|
75
|
+
ret
|
76
|
+
end
|
77
|
+
|
78
|
+
def edit
|
79
|
+
tmp = File.open("fs-ticket-edit.txt", "w+")
|
80
|
+
tmp.puts({"title" => @ticket.title,
|
81
|
+
"status" => @ticket.status,
|
82
|
+
"priority" => @ticket.priority,
|
83
|
+
"type" => @ticket.type,
|
84
|
+
"comment" => @ticket.comments}.to_yaml)
|
85
|
+
tmp.close
|
86
|
+
|
87
|
+
system("vim fs-ticket-edit.txt")
|
88
|
+
|
89
|
+
#Restore curses options
|
90
|
+
Curses.raw
|
91
|
+
Curses.nonl
|
92
|
+
#Curses.cbreak
|
93
|
+
Curses.noecho
|
94
|
+
Curses.curs_set(0)
|
95
|
+
@screen.scrollok(true)
|
96
|
+
@screen.keypad(true)
|
97
|
+
end
|
98
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fs-ticket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark McCurry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -55,8 +55,13 @@ files:
|
|
55
55
|
- lib/render.rb
|
56
56
|
- lib/ticket.rb
|
57
57
|
- lib/view/add-ticket-view.rb
|
58
|
+
- lib/view/add-ticket-view.rb~
|
59
|
+
- lib/view/edit-ticket-view.rb
|
60
|
+
- lib/view/edit-ticket-view.rb~
|
58
61
|
- lib/view/report-view.rb
|
62
|
+
- lib/view/report-view.rb~
|
59
63
|
- lib/view/ticket-view.rb
|
64
|
+
- lib/view/ticket-view.rb~
|
60
65
|
- lib/widget/button-widget.rb
|
61
66
|
- lib/widget/dropdown-widget.rb
|
62
67
|
- lib/widget/text-field-widget.rb
|